1

I have a task. It says I have to make a template function this kind template <typename T> int reduce(T ar[], int n);. This function does sort from min up to max value and delete equal values. Also it says I have to make it using STL. I do not need solution but only advice what should I do. Here it is my solution.

template <typename T>
int reduce(T ar[], int n)
{
    ostream_iterator<int, char> out_iter(cout, " ");

    T * iter_begin = ar;
    T * iter_end = ar + n;

    sort(iter_begin, iter_end);
    copy(iter_begin, iter_end, out_iter);
    cout << endl;

    iter_end = unique(iter_begin, iter_end);
    copy(iter_begin, iter_end, out_iter);

    //erase(iter_begin, iter_end);

    return 0;
}

void main()
{
    srand((unsigned)time(NULL));


    int size = 20;
    long * mas = new long[size];

    for (int i = 0; i < size; i++)
        mas[i] = rand() % size + 1;

    reduce(mas, size);

    string str = "hello how are you doing";
    reduce(&str, str.length());

    delete[] mas;
}
Mikhail
  • 1,092
  • 1
  • 11
  • 30
  • 2
    What does not work in your solution? – Slava Aug 14 '15 at 17:48
  • @Slava VS says error is in the `sort()` if I use `std::string` – Mikhail Aug 14 '15 at 17:51
  • 1
    `string str = "hello how are you doing"; reduce(&str, str.length());` is not what you want. You tell it you're passing an array of `string` objects, with a length of `str.length()`, but you're really passing it a pointer to a single `string`. – Chad Aug 14 '15 at 17:58

2 Answers2

1

Your reduce function expects an array but you are passing the address of the string in reduce(&str, str.length());. This makes it behave as you passed an array of std::string with a size of str.length(). What you need to do is convert the string to a char array and then pass it to the function.

Community
  • 1
  • 1
NathanOliver
  • 150,499
  • 26
  • 240
  • 331
  • 2
    @Mikhail in reality the function should take "iterators" like the standard function does and then you function would look like `template void reduce(RandomAcessIterator beginning, RandomAcessIterator end)` – NathanOliver Aug 14 '15 at 18:14
  • Actually I know hot make it with some other ways, but it says I have to do it using STL methods only. – Mikhail Aug 14 '15 at 18:20
  • 1
    @Mikhail I just wanted to point out that you didn't have the requirement to take an array that is the way a function like that should be written so you can use it with arrays and standard containers. – NathanOliver Aug 14 '15 at 18:23
1

if you are using STL you should make your function the same way as STL algorithms implemented, like std::sort that you use:

template <typename Iter>
int reduce(Iter iter_begin, Iter iter_end )
{
    ostream_iterator<int, char> out_iter(cout, " ");

    sort(iter_begin, iter_end);
    copy(iter_begin, iter_end, out_iter);
    cout << endl;

    iter_end = unique(iter_begin, iter_end);
    copy(iter_begin, iter_end, out_iter);

    //erase(iter_begin, iter_end);

    return 0;
}

int main()
{
    srand((unsigned)time(NULL));

    const int size = 20;
    long mas[size];

    for (int i = 0; i < size; i++)
        mas[i] = rand() % size + 1;

    reduce(mas, mas + size);

    string str = "hello how are you doing";
    reduce(str.begin(), str.end());
    return 0;
}

As you have to use your interface you will have to use char array instead of std::string, something like this:

char str[] = "hello how are you doing";
int len = reduce( str, strlen( str ) );
str[len] = 0;

you also need to fix your function reduce to return count of unique elements instead of 0.

Slava
  • 40,641
  • 1
  • 38
  • 81
  • @ Slava thank you this is great solution, but I am not allowed to use any containers. – Mikhail Aug 14 '15 at 18:39
  • 1
    @Mikhail technically speaking `std::string` is a container. But I changed example to use array instead of `std::vector` already anyway. Your original dynamically allocated array will work as well i just do not see why you need it. – Slava Aug 14 '15 at 18:42
  • @ Slava main problem is I have to delete all equal values from an array. – Mikhail Aug 14 '15 at 18:46
  • @Mikhail what do you mean by delete? You cannot do that on dynamically allocated array either. – Slava Aug 14 '15 at 18:55
  • @ Slava I thought I couldn't do it because of my low quality knowledge. Mean by delete. Reduce array size from 10 to 6 for example. – Mikhail Aug 14 '15 at 19:03
  • @ Slava here it is a link with a screenshot what I have to make http://prntscr.com/84npy8 – Mikhail Aug 14 '15 at 19:07
  • @Mikhail in this case you have to keep interface, move duplicates to the end and return count of unique elements. You are close, you just need to `return std::distance( iter_end, iter_beg );` instead of `return 0;` and modify code not to use `std::string` but char array. – Slava Aug 14 '15 at 20:39