-4

Take a vector of vector of int's how do I print all of them from begin to end

for(row=v.begin();row!=v.end();row++){
        for(col=row->begin();col!=row->end();col++){
            //cout<<? 
        }
    }

What should be used in inner for loop to print each element

Jérôme
  • 8,016
  • 4
  • 29
  • 35
Varun Teja
  • 503
  • 2
  • 6
  • 16

3 Answers3

1

Personally, I like iterating over vectors just using a simple for loop from 0 to size(), but this is how you would do it with iterators:

for(vector< vector<int> >::iterator row = v.begin(); row != v.end(); ++row) {
    for(vector<int>::iterator col = row->begin(); col != row->end(); ++col) {
        cout << *col;
    }
}

See: Iteration over std::vector: unsigned vs signed index variable

Community
  • 1
  • 1
Gillespie
  • 5,780
  • 3
  • 32
  • 54
  • 1
    Iterating with iterators is preferred as it can be faster. Also if you put `size()` in the for loop condition it may call `size()` every iteration which is a lot of extra function calls. IMHO a ranged based for loop should be used. – NathanOliver Feb 11 '16 at 15:03
  • @songyuanyao I know that. I was commenting to the answerer about him saying *I like iterating over vectors just using a simple for loop from 0 to size()* – NathanOliver Feb 11 '16 at 15:06
  • @NathanOliver It's true, but when you aren't super worried about efficiency, I think iterators are overly verbose syntactically (esp. in C++98). It makes your code less readable, IMO, and I value readability over efficiency in many cases. – Gillespie Feb 11 '16 at 15:19
  • A `typedef ` can fix that very easily. I try to code for readability as well unless I suspect it will hurt performance and multiple unnessacary function calls falls under that. Since so much of the standard is iterator based most people should be used to working with them and reading the syntax. – NathanOliver Feb 11 '16 at 15:23
  • @NathanOliver Why would it call `size()` every iteration through the loop, but not `end()`? Aren't they both functions? – Gillespie Feb 11 '16 at 15:42
  • They are. I would not actually call end but capture the end iterator so I only call the function once per row. As I said this is a reason to prefer a ranged based for loop as it handles all of this for you. `for (const auto& row : v) for(const auto & col : row) std::cout << col;` looks very clean and doesn't have any unnecessary function calls. see this example: http://coliru.stacked-crooked.com/a/f87f771cc0fceae8 – NathanOliver Feb 11 '16 at 16:06
1

v.begin() returns an iterator to the beginning of the sequence
v.end() returns an iterator to the element past the end of the sequence

You can loop through your structure using those iterators:

for(auto it_row =v.begin(); it_row!=v.end(); it_row++){
    for(auto it_col=it_row->begin();it_col!=it_row->end();it_col++){
        cout<<*it_col<<endl;
    }
}

In order to deference (get the value) your iterator you need to use the following syntax: *it_col

I used auto (C++ 11) instead of explicitly putting the iterator type:

vector<vector<int>>::const_iterator it_row = v.begin()
vector<int>::const_iterator it_col = it_row->begin()

You can find more details about iterators here.

Jérôme
  • 8,016
  • 4
  • 29
  • 35
0

If you are using c++11 then, you can use range based for loop;

for (const auto & items : v)
    for (const auto & item : items)
        cout << item;
Praveen
  • 8,945
  • 4
  • 31
  • 49