iterating over vector elements backwards

302 views Asked by At

I am trying to implement a small program that iterates over a 2d vector backwards and adds the value of the element.

If that element have already been added then I want to overwrite the value of the vector with 99.

So for example if number of climbs is four then add the of the program points should have the value 5 and the vector should look like this at the end

{1, 1 ,1},

{99, 1, 1},

{99(should start here), 99, 99} 

But I keep getting a segmentation fault and I don't know whether I am iterating over the vector backwards incorrectly.

This is my full code

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

int main()
{
    vector<vector<int>> vect
    {   {3}, //finish here
     
        {1, 1 ,1},
     
        {2, 1, 1},
     
        {1, 1, 1}  //start here
    };

    int points = 0;
    
    for (int i = 0; i < vect.size(); i++)
    {
        for (int j = 0; j < vect[i].size(); j++)
        {
            cout << vect[i][j] << " ";
        } 
        cout << endl;
    }
  
   int visited = 99;
   int number_of_climbs = 4;
  
   for(int i = 4; i >= 0; i--)
       for (int j = 0; j < number_of_climbs; j++)
       {
            if(vect[i][j] != 99)
            {
              points += vect[i][j];
              vect[i][j] = 99;;
              continue;
            }
       } 

    return 0;
}
1

There are 1 answers

0
Tas On

Looping over things backwards always trips me up too, especially when I accidentally declare my loop using an unsigned int. Your backwards loop is close to correct, but can be simplified into:

for (int i = vect.size() - 1; i >= 0; --i)
{
    for (int j = vect[i].size() - 1; j >= 0; --j)
    {
    }
}

You need to start at size() - 1 because the only indices available are [0, size) (that is EXCLUSIVE of size), so in a vector of 4 elements, that's 0, 1, 2 and 3 (and you need to start at 3), which is likely the cause of your segmentation fault since you start your initial loop at 4 so it's immediately out-of-bounds.

Here in the inner loop you can see we account for the vectors being different sizes by just using the size of each vector.

It's also possible to use reverse iterators, but iterators can be confusing to people:

for (auto outer = vect.rbegin(); outer != vect.rend(); ++outer)
{
    for (auto inner = outer->rbegin(); inner != (*outer).rend(); ++inner)
    {
    }
}

Note I've shown both ways to access the iterator, using it-> or (*it). Within the inner loop, you will simply use *inner to get the actual value held by the vector, so if you simply had std::cout << *inner << " "; that would print the 2d vector on one line in reverse order.

Even though we're looping in reverse, we still use ++