2

This is my first ever post on this site as a C++ beginner. My question is rather simple. Write a function that reverse the order of elements in a vector. For example, 1, 3, 5, 7, 9 becomes 9, 7, 5, 3, I. The reverse function should produce a new vector with the reversed sequence, leaving its original vector unchanged.

And here is my code. When I run it there is nothing coming after the word "Printing". I am pretty sure I made a silly and simple mistake somewhere but just couldn't figure it out. Would appreciate any help.Cheers.

void reverse_a(const vector<int>&v1, vector<int>&v2)
{
    //this function creates vector2 with the reverse sequence of elements from vector 1


  for(int i=v1.size()-1;i<=0;--i)

  { 
      v2.push_back(v1[i]);

  }
}

void print(const vector<int>&v)
{
    cout<<"Printing"<<endl;
    for(int i=0;i<v.size();++i)
        cout<<v[i]<<",";
    cout<<"\n"<<"end of print.\n";
}

int main()
{
    vector<int>v1;
    vector<int>v2;
    int input;
    while(cin>>input)
        v1.push_back(input);
    reverse_a(v1,v2);

    print(v2);

    keep_window_open("`");

}
Ralf Zhang
  • 171
  • 1
  • 2
  • 4
  • What happens when you step through your code in a debugger? – tmyklebu Sep 24 '14 at 06:15
  • Please post an [MCVE](http://stackoverflow.com/help/mcve) and remove irrelevant code. Your reversing function has a comment in it which is suspicious. What are you really doing there? Also, vectors have reverse iterators. And constructors that take iterator pairs. – juanchopanza Sep 24 '14 at 06:16
  • Possible duplicate of [How do I reverse a C++ vector?](http://stackoverflow.com/questions/8877448/how-do-i-reverse-a-c-vector) – rold2007 May 10 '16 at 23:28

5 Answers5

9
std::vector<int> reverse(std::vector<int>v)
{
  std::reverse(v.begin(),v.end());
  return v;
}
TNA
  • 2,595
  • 1
  • 14
  • 19
  • 1
    @Robert Mutke Yes because you should leave the original vector unchanged, therefor I make a copy. – TNA Sep 24 '14 at 08:15
  • use ``reverse_copy`` then – Robert Mutke Sep 24 '14 at 08:43
  • 2
    @Robert Mutke Using `reverse_copy` would be much more verbose without any real benefit. On the contrary: My solution is move-optimized and let the caller decide if he wants a copy or to move the string in instead. – TNA Sep 24 '14 at 08:59
8
for(int i=v1.size()-1;i<=0;--i)
//                    ^^^^

That middle bit i <= 0 is the continuation clause and must be true for the loop to iterate. It won't ever be true unless your vector is empty or of size one, in which case you'll get an error when you try to access v1[-1].

Change the <= to a >=.


Mind you, I'm also not a big fan of passing in a vector (even as a reference) to be modified, since there's no guarantee to the function it won't already have something in it. I think it makes more sense to create the target vector new within the function and pass it back, something like:

#include <iostream>
#include <vector>
using namespace std;

vector<int> reverse_a (const vector<int> &v1) {
    vector<int> v2;
    size_t i = v1.size();
    while (i > 0)
        v2.push_back (v1[--i]);
    return v2;
}

void print (const vector<int> &v) {
    cout << "Printing" << endl;
    for (size_t i = 0; i < v.size(); ++i)
        cout << v[i] << ",";
    cout << "\nEnd of print.\n";
}

int main (void) {
    int input;
    vector<int> v1;
    while (cin >> input)
        v1.push_back (input);

    vector<int> v2 = reverse_a (v1);
    print (v2);

    return 0;
}

You'll also notice I've changed to using size_t as the index type and made adjustments to ensure it doesn't go negative.


This is all assuming, of course, that you're trying to learn relatively simple concepts of programming. Professional C++ programmers would probably use an iterator to populate a new vector, along the lines of:

vector<int> reverse_a (vector<int> &v1) {
    vector<int> v2;
    vector<int>::iterator it = v1.end();
    while (it != v1.begin())
        v2.push_back (*(--it));
    return v2;
}

or with the minimalist (no function call needed other than the standard library ones):

vector<int> v2 (v1.rbegin(), v1.rend());

Once you've committed to learning C++, you should do so with gusto. There's nothing quite so bad as a half-convert to the language :-)

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • 2
    Further info - this loop is not well-defined when the vector is empty (because `v1.size()` is a `size_t` which is unsigned). A more solid way to write the loop (if you don't want to use reverse iterators of course) is `for (size_t i = v1.size(); i--; )` . – M.M Sep 24 '14 at 06:24
  • 1
    Thanks, @Matt, I've made changes as per your suggestion, with some slight changes due to my own programming prejudices :-) – paxdiablo Sep 24 '14 at 06:36
  • Why not use `std::reverse(vec.begin(), vec.end());` instead.. :S – Brandon Sep 24 '14 at 07:13
  • @Brandon, you could, but I think the intent of the work is to teach deeper coding concepts than that :-) But I'll mention that as an option. – paxdiablo Sep 24 '14 at 07:52
  • 2
    A professional C++ programmer would either use `std::reverse` (for in place modification), or `std::vector reversed( original.rbegin(), original.rend() );` (for a new one). But I suspect the goal here is to learn how to do such things himself. – James Kanze Sep 24 '14 at 09:21
  • James, see the last code section of the answer, I've already provided that, but you're right about the other stuff, educator may not even _know_ about iterators :-) – paxdiablo Sep 24 '14 at 09:26
1

Use algorithm reverse. It takes bidirectional iterators, so you pass begin() and end():

int main(void)
{
    std::vector<int> v{1, 2, 3, 4};
    std::cout << "vector: ";
    for (int i: v)
      std::cout << i << ", ";
    std::cout << "\n";
    std::reverse(v.begin(), v.end());
    std::cout << "reversed vector: ";
    for (int i: v)
      std::cout << i << ", ";
    std::cout << "\n";

    return 0;

}

If you need a copy, then go for: reverse_copy

Robert Mutke
  • 2,757
  • 1
  • 16
  • 14
0

You confound <= with >=.

But using reverse_iterator would make the job simpler

void reverse_a(const std::vector<int>&v1, std::vector<int>&v2)
{
    v2.clear();
    for (std::vector<int>::const_reverse_iterator it = v1.rbegin(); it != v1.rend(); ++it) {
        v2.push_back(*it);
    }
}

Note: it is a good place to use auto (in C++11) instead of the long type here:

for (auto it = v1.rbegin(); it != v1.rend(); ++it)

And the code can even be simplified to:

void reverse_a(const std::vector<int>&v1, std::vector<int>&v2)
{
    v2.assign(v1.rbegin(), v1.rend());
}
Jarod42
  • 203,559
  • 14
  • 181
  • 302
-1

You can try swapping the values using the iterator.

Something like :

Iterator first = vec.begin();
Iterator last = vec.end();

while ((first!=last)&&(first!=--last)) 
{
    std::iter_swap (first,last);
    ++first;
}
  • 1
    Note the requirements: "The reverse function should produce a new vector with the reversed sequence, leaving its original vector unchanged. " – The Dark Sep 24 '14 at 07:21