Iterate over vector of pair
Asked Answered
C

4

12

I have written following code snippet but it does not seem to be working.

int main(){
    int VCount, v1, v2;
    pair<float, pair<int,int> > edge;
    vector< pair<float, pair<int,int> > > edges;
    float w;
    cin >> VCount;
    while( cin >> v1 ){
        cin >> v2 >> w;
        edge.first = w;
        edge.second.first = v1;
        edge.second.second = v2;
        edges.push_back(edge);
    }
    sort(edges.begin(), edges.end());
    for ( vector < pair<float,pair<int,int>> >::const_iterator it = edges.begin() ; itt != edges.end; it++){
        cout >> it.first;
    }
    return 0;
}

It is throwing an error at the line containing for loop. The error is:

error: no match for ‘operator<’ in ‘it < edges.std::vector<_Tp, _Alloc>::end [with _Tp = std::pair<float, std::pair<int, int> >, _Alloc = std::allocator<std::pair<float, std::pair<int, int> > >, std::vector<_Tp, _Alloc>::const_iterator = __gnu_cxx::__normal_iterator<const std::pair<float, std::pair<int, int> >*, std::vector<std::pair<float, std::pair<int, int> > > >, typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::const_pointer = const std::pair<float, std::pair<int, int> >*]

Can anyone help me out?

Ceroplastic answered 1/9, 2014 at 12:41 Comment(7)
shouldn't that be it != edges.end()? I don't see a itt declared anywhereKahn
Another wild punt does it work if you add a space between your angle brackets in your for loop: vector < pair<float,pair<int,int> > >::const_iterator?Kahn
@EdChum: right angle bracket problem was solved since C++11Plataea
@PiotrS. Depends on compiler that's why it's a wild puntKahn
@EdChum: no, every C++11 compiler must properly handle >>Plataea
You should post the real code. The code above would "throw" more errors than that.Homily
@PiotrS. no indication here that this is C++11, you are correct but I wanted to make the point that some compilers don't handle this pre c++11Kahn
M
16

There are at least three errors in the loop.

for ( vector < pair<float,pair<int,int>> >::const_iterator it = edges.begin() ; itt != edges.end; it++){
        cout >> it.first;
    }

First of all you have to use edges.end() instead of edges.end. And inside the body there has to be

    cout << it->first;

instead of

    cout >> it.first;

To escape such errors you could write simply

for ( const pair<float, pair<int,int> > &edge : edges )
{
   std::cout << edge.first;
}
Mondrian answered 1/9, 2014 at 12:49 Comment(6)
I am confused when to use -> and when to use .. Could you please help?Ceroplastic
@Ceroplastic iterators like pointers pointers are also particular kinds of iterators). When you for example have a pointer to an object of std::pair then you use p->first, p->second. The same way iterators are used.Mondrian
Or just for ( const auto& edge : edges )Schlep
@VladfromMoscow The following code works for me, but it shouldn't according to you, if I understand you correctly? (has this issue been fixed in c++17 by any chance maybe?) Graph::Graph(vector<pair<int, int>>& edges, int nVert) { adjList.resize(nVert); for(auto i: edges) { adjList[i.first].push_back(i.second); adjList[i.second].push_back(i.first); } @AntonSavin will auto give it some other kind of iterator than a manually assigned vector < pair<float,pair<int,int>> >::const_iterator?Thrush
@gh05t Here you are using the range based for loop shown in the end of my answer.Mondrian
Oh right it will de-reference the iterator internally and you won't have to do it manually then got it, thanks! (brain fart moment lol)Thrush
O
17

C++14 iterators are a lot simpler

for (const auto& pair : edges)
{
    std::cout << pair.first;
}

C++17 iterators allow deeper access

for (const auto& [first, sec] : edges)
{
    std::cout << first;
}
Oder answered 20/1, 2022 at 18:8 Comment(0)
M
16

There are at least three errors in the loop.

for ( vector < pair<float,pair<int,int>> >::const_iterator it = edges.begin() ; itt != edges.end; it++){
        cout >> it.first;
    }

First of all you have to use edges.end() instead of edges.end. And inside the body there has to be

    cout << it->first;

instead of

    cout >> it.first;

To escape such errors you could write simply

for ( const pair<float, pair<int,int> > &edge : edges )
{
   std::cout << edge.first;
}
Mondrian answered 1/9, 2014 at 12:49 Comment(6)
I am confused when to use -> and when to use .. Could you please help?Ceroplastic
@Ceroplastic iterators like pointers pointers are also particular kinds of iterators). When you for example have a pointer to an object of std::pair then you use p->first, p->second. The same way iterators are used.Mondrian
Or just for ( const auto& edge : edges )Schlep
@VladfromMoscow The following code works for me, but it shouldn't according to you, if I understand you correctly? (has this issue been fixed in c++17 by any chance maybe?) Graph::Graph(vector<pair<int, int>>& edges, int nVert) { adjList.resize(nVert); for(auto i: edges) { adjList[i.first].push_back(i.second); adjList[i.second].push_back(i.first); } @AntonSavin will auto give it some other kind of iterator than a manually assigned vector < pair<float,pair<int,int>> >::const_iterator?Thrush
@gh05t Here you are using the range based for loop shown in the end of my answer.Mondrian
Oh right it will de-reference the iterator internally and you won't have to do it manually then got it, thanks! (brain fart moment lol)Thrush
P
4
for ( vector < pair<float,pair<int,int>> >::const_iterator it = edges.begin() ; 

     it != edges.end () ;  // Use (), and assuming itt was a typo
     it++)
{
    cout << it->first; // Use -> 
}

Also, you might want to add a custom comparator for std::sort

Pietra answered 1/9, 2014 at 12:46 Comment(2)
How should I add a custom sort? Is it better to use a struct or class rather than making a vector of pair (which contains a float and a pair)?Ceroplastic
@Ceroplastic Either use a lambda or a functor as third parameter for std::sort, where you may choose to perform sorting on desired pair element. Search on SO, there's several examples. If really lost ask a new questionPietra
P
1
vector<pair<int,int>>v;  // <-- for this one

for(int i=0;i<n;i++){
    int x,y;
    cin>>x>>y;
    v.push_back(make_pair(x,y));
}

sort(v.begin(),v.end(),compare);

for( vector<pair<int,int>>::iterator p=v.begin(); p!=v.end(); p++){
    cout<<"Car "<<p->first<<" , "<<p->second<<endl;
}
cout<<endl;

// you can also write like this

for(auto it:v){
    cout<<"Car "<<it.first<<" , "<<it.second<<endl;
}
cout<<endl;

// you can also write like this

for(pair<int,int> it2:v){
    cout<<"Car "<<it2.first<<" , "<<it2.second<<endl;
}
// now you can code for your one by taking reference from this ok
Primm answered 6/10, 2020 at 14:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.