Connecting Tech Pros Worldwide Forums | Help | Site Map

template function to accept vector and array

utab
Guest
 
Posts: n/a
#1: Aug 28 '08
Dear all,

I have the below template (1) which I would like to implement to accept
either a vector or an array. I thought on it some time and came with a
solution as in (2) , however the call of my implementation is not natural
in the way that I do not supply the vector directly. How can I improve on
that?

(1)
template <class T>
T median(vector<Tv)
{
vec_sz size = v.size();
if (size == 0)
throw domain_error("median of an empty vector");
sort(v.begin(), v.end());
vec_sz mid = size/2;
return size % 2 == 0 ? (v[mid] + v[mid-1]) / 2 : v[mid];
}

(2)
template <class T>
T median( T*v, int n )
{
size_t sz = n;
if (n == 0)
throw domain_error("median of an empty vector");
sort(v, v+n);
size_t mid = sz/2;
return sz % 2 == 0 ? (v[mid] + v[mid-1]) / 2 : v[mid];
}

calls for (2) are

std::cout << median(a,7) << std::endl; // for array
....
std::cout << median(&(*b.begin()),b.size()) << std::endl; // for vector

Best regards,


Victor Bazarov
Guest
 
Posts: n/a
#2: Aug 28 '08

re: template function to accept vector and array


utab wrote:
Quote:
Dear all,
>
I have the below template (1) which I would like to implement to
accept either a vector or an array. I thought on it some time and
came with a solution as in (2) , however the call of my
implementation is not natural in the way that I do not supply the
vector directly. How can I improve on that?
>
(1)
template <class T>
T median(vector<Tv)
{
vec_sz size = v.size();
if (size == 0)
throw domain_error("median of an empty vector");
sort(v.begin(), v.end());
vec_sz mid = size/2;
return size % 2 == 0 ? (v[mid] + v[mid-1]) / 2 : v[mid];
}
>
(2)
template <class T>
T median( T*v, int n )
{
size_t sz = n;
if (n == 0)
throw domain_error("median of an empty vector");
sort(v, v+n);
size_t mid = sz/2;
return sz % 2 == 0 ? (v[mid] + v[mid-1]) / 2 : v[mid];
}
>
calls for (2) are
>
std::cout << median(a,7) << std::endl; // for array
...
std::cout << median(&(*b.begin()),b.size()) << std::endl; // for
vector
>
The best approach would actually be to implement it _once_ by
supplying two iterators to your sequence:

template<class Iterator>
typename Iterator::value_type median(Iterator b, Iterator e)
{
...
}

Instead of doing it with overloading. Then you'll be able to pass
your sequence like so

median(v.begin(), v.end());

median(a, a+7);

I'll leave the implementation to you. It's not that difficult,
really. See the function 'distance' for working with iterators.
It's quite efficient with random-access iterators.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


Jim Z. Shi
Guest
 
Posts: n/a
#3: Aug 28 '08

re: template function to accept vector and array


try this:

template<typename Iter>
double median(Iter begin, Iter end)
{
typedef typename iterator_traits<Iter>::difference_type diff_t;
diff_t size = end - begin;
if(0 == size )
throw std::runtime_error("median of empty vector");

sort(begin, end);
diff_t mid = size / 2;
return size % 2 == 0 ? (*(begin+mid-1)+*(begin+mid))/2 : *(begin+mid);
}

int main() {
int arr[] = { 0, 3, 11, 9 };
int arr_size = sizeof(arr)/sizeof(int);
vector<intvec(arr, arr + arr_size);

cout << "arr midian: " << median(arr, arr + arr_size) << endl;
cout << "vec median: " << median(vec.begin(), vec.end()) << endl;

return 0;
}

HTH,
jim

utab 写道:
Quote:
Dear all,
>
I have the below template (1) which I would like to implement to accept
either a vector or an array. I thought on it some time and came with a
solution as in (2) , however the call of my implementation is not natural
in the way that I do not supply the vector directly. How can I improve on
that?
>
(1)
template <class T>
T median(vector<Tv)
{
vec_sz size = v.size();
if (size == 0)
throw domain_error("median of an empty vector");
sort(v.begin(), v.end());
vec_sz mid = size/2;
return size % 2 == 0 ? (v[mid] + v[mid-1]) / 2 : v[mid];
}
>
(2)
template <class T>
T median( T*v, int n )
{
size_t sz = n;
if (n == 0)
throw domain_error("median of an empty vector");
sort(v, v+n);
size_t mid = sz/2;
return sz % 2 == 0 ? (v[mid] + v[mid-1]) / 2 : v[mid];
}
>
calls for (2) are
>
std::cout << median(a,7) << std::endl; // for array
...
std::cout << median(&(*b.begin()),b.size()) << std::endl; // for vector
>
Best regards,
>
Jim Z. Shi
Guest
 
Posts: n/a
#4: Aug 28 '08

re: template function to accept vector and array


then this?

template<typename Iter>
typename iterator_traits<Iter>::value_type median(Iter begin, Iter end)
{
typedef typename iterator_traits<Iter>::difference_type diff_t;
diff_t size = end - begin;
if(0 == size )
throw std::runtime_error("median of empty vector");

size 0 ? sort(begin, end) : sort(end, begin);
diff_t mid = size / 2;
return size % 2 == 0 ? (*(begin+mid-1)+*(begin+mid))/2 : *(begin+mid);
}

int main()
{
int arr[] = { 0, 3, 11, 6 };
int arr_size = sizeof(arr) / sizeof(int);
vector<floatvec(arr, arr + arr_size);

cout << "int arr midian: " << median(arr, arr + arr_size) << endl;
cout << "float vec median: " << median(vec.begin(), vec.end()) << endl;
cout << "inverse: " << median(arr + arr_size, arr) << endl;
return 0;
}

jim

Jim Z. Shi 写道:
Quote:
try this:
>
template<typename Iter>
double median(Iter begin, Iter end)
{
typedef typename iterator_traits<Iter>::difference_type diff_t;
diff_t size = end - begin;
if(0 == size )
throw std::runtime_error("median of empty vector");
>
sort(begin, end);
diff_t mid = size / 2;
return size % 2 == 0 ? (*(begin+mid-1)+*(begin+mid))/2 : *(begin+mid);
}
>
int main() {
int arr[] = { 0, 3, 11, 9 };
int arr_size = sizeof(arr)/sizeof(int);
vector<intvec(arr, arr + arr_size);
>
cout << "arr midian: " << median(arr, arr + arr_size) << endl;
cout << "vec median: " << median(vec.begin(), vec.end()) << endl;
>
return 0;
}
>
HTH,
jim
>
utab 写道:
Quote:
>Dear all,
>>
>I have the below template (1) which I would like to implement to
>accept either a vector or an array. I thought on it some time and came
>with a solution as in (2) , however the call of my implementation is
>not natural in the way that I do not supply the vector directly. How
>can I improve on that?
>>
>(1)
>template <class T>
>T median(vector<Tv)
>{
> vec_sz size = v.size();
> if (size == 0)
> throw domain_error("median of an empty vector");
> sort(v.begin(), v.end());
> vec_sz mid = size/2;
> return size % 2 == 0 ? (v[mid] + v[mid-1]) / 2 : v[mid];
>}
>>
>(2)
>template <class T>
>T median( T*v, int n )
>{
> size_t sz = n;
> if (n == 0)
> throw domain_error("median of an empty vector");
> sort(v, v+n);
> size_t mid = sz/2;
> return sz % 2 == 0 ? (v[mid] + v[mid-1]) / 2 : v[mid];
>}
>>
>calls for (2) are
>>
>std::cout << median(a,7) << std::endl; // for array
>...
>std::cout << median(&(*b.begin()),b.size()) << std::endl; // for vector
>>
>Best regards,
>>
Closed Thread