简体   繁体   中英

advancing a iterator by 1 in c++ STL

I am trying to implement linked list which removes all the nodes which have a greater value on right side.

eg The list 12->15->10->11->5->6->2->3->NULL should be changed to 15->11->6->3->NULL . Note that 12, 10, 5 and 2 have been deleted because there is a greater value on the right side.

So, the algorithm i thought was to create a list and then place two iterators at beginning and another at beginning+1 and to check for the condition and remove the node if its greater.

Code

#include<iostream>
#include<iterator>
#include<vector>
#include<list>
#include<algorithm>

using namespace std;

int main(){

    list <int> a;
    list <int>::iterator it, b, c;

    a.push_back(12);
    a.push_back(15);
    a.push_back(10);
    a.push_back(11);
    a.push_back(5);
    a.push_back(6);
    a.push_back(2);
    a.push_back(3);

    b = a.begin();
    c = a.begin()+1;


    for(it=a.begin();it!=a.end();it++){
         if(*b<*c){
            a.remove(*b);
            b++;
            c++;
        }
        cout << *it;
    }
    return 0;
}

But I get this error

ctest.cpp:24:10: error: no match for ‘operator+’ (operand types are ‘std::list<int>::iterator {aka std::_List_iterator<int>}’ and ‘int’)

(Not sure about your logic) But, std::list iterators are BidirectionalIterator so operator+ and operator- is not available here

You can use std::advance

Lists iterators allow only the use of the ++ operators to move; the idea is that in a linked list the "natural", cheap operation is to move in single steps (moving of n steps is O(n)), so iterators allow just that.

So, in your code the fix is just to replace

c = a.begin()+1;

with

c=b;
++c;

In the general case, instead, when you need to advance an iterator of n places regardless of whether it defines the + operator, you can use std::advance .

There are some logic errors in your code:

  1. What if a list will have two equal elements ? list::remove will remove both of them. For example: 4->5->4->3 will be 5->3 that is not a thing that you expected.. Yes ?
  2. What if the first element will be greater then second ? In this case iterators b and c will be not incremented at all
  3. At the end of a list iterator c will point out of list and if(*b<*c){ will fail

Maybe this - http://ideone.com/9NQAB1 - is what you wanted ?

From C++11, you can use std::next, and std::prev on iterators to make it step forward or backward certain offset. Please refer to the documents and examples about std::next and std::prev in cppreference.

Add Two Point

1

b = a.begin();
c = a.begin()+1;

b or c may be invalid , iterator can't be assigned like this, it's very dangerous.

2 you remove a elem when you traverse the list, And the iterator may be invalid after you remove.For example :

int myints[]= {17,89,7,14};
  std::list<int> mylist (myints,myints+4);
  for (std::list<int>::iterator it=mylist.begin(); it!=mylist.end(); ++it){
    std::cout << ' ' << *it<<std::endl;
    if( *it==89){
        mylist.remove(89);
    }
  }

outputs

 17
 89

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM