Programmerzzz
Programmerzzz

Reputation: 1287

Get Next Element in the std::list using iterator

I am trying to get difference between consecutive elements in a std::list. I attempted the following solution but as this thread says, I need to make a copy of iterator and increment it. Not sure what it mean since adding number to iterators also result in error. what am I missing here. I am using a previous version of C++ but not C++ 11

#include "stdafx.h"
#include <list>
#include <iostream>
using namespace std;

int main()
{
    std::list<int> myList;
    //for (int i = 10;i < 15;i++)
    myList.push_back(12);
    myList.push_back(15);
    myList.push_back(18);
    myList.push_back(19);
    myList.push_back(25);

    for (std::list<int>::const_iterator itr = myList.begin();itr != myList.end();++itr)
    {
        int x = *itr;
        int y = *(itr + 1);
        int diff = std::abs(x - y);
        cout << diff << "\n";
    }

    return 0;
}

Upvotes: 1

Views: 8113

Answers (7)

Drunk Engineer
Drunk Engineer

Reputation: 13

I think you need two iterator to solve this question Here's my code

#include "stdafx.h"
#include <list>

#include <iterator>
#include <iostream>

using namespace std;

int main()
{
    std::list<int> myList;
    //for (int i = 10;i < 15;i++)
    myList.push_back(12);
    myList.push_back(15);
    myList.push_back(18);
    myList.push_back(19);
    myList.push_back(25);
    int x = 0;
    int y = 0;
    std::list<int>::iterator itr;
    std::list<int>::iterator it_next;

    for (itr = myList.begin(), it_next = ++myList.begin();it_next != myList.end();itr++, it_next++)
    {

        x = *itr;
        y = *it_next;
        int diff = abs(x - y);
        cout << diff << "\n";
    }

    system("PAUSE");
    return 0;
}

I build it in VC++2005 but it should work fine in C++
Hope this will help you :)

Upvotes: 1

binarybarbarian
binarybarbarian

Reputation: 65

Another way would be to simply keep track of the previous list element value, not the iterator, and to subtract that previous value from the element the iterator is currently pointing to; like so:

#include <list>
#include <cmath> // need cmath for std::abs
#include <iostream>
using namespace std;

int main()
{
  std::list<int> myList;
  //for (int i = 10;i < 15;i++)
  myList.push_back(12);
  myList.push_back(15);
  myList.push_back(18);
  myList.push_back(19);
  myList.push_back(25);
  int PreviousElement = 0;
  bool Start = false;
  for (std::list<int>::const_iterator itr = myList.begin(); itr != myList.end(); ++itr)
  {
    if (Start)
    {
      int diff = std::abs(*itr - PreviousElement);
      cout << diff << "\n";
    }
    else
    {
      Start = true;
    }
    PreviousElement = *itr;
  }

  return 0;
}

Upvotes: 1

Gor Asatryan
Gor Asatryan

Reputation: 924

#include <list>
#include <iostream>

int main()
{
    std::list<int> myList;
    //for (int i = 10;i < 15;i++)
    myList.push_back(12);
    myList.push_back(15);
    myList.push_back(18);
    myList.push_back(19);
    myList.push_back(25);
    for (std::list<int>::const_iterator itr = myList.begin();
                              itr != std::prev(myList.end());
                                                      ++itr)
    {
        std::list<int>::const_iterator nextIt = std::next(itr);
        int diff = *itr - *nextIt;
        std::cout << diff << "\n";
    }

    return 0;
}

Use std::next(itr) to get next iterator and use std::prev(myList.end()) in for loop to get previous of last element in list.

Also you can change your for loop and use std::advance() to get next iterator without using std::next and std::prev

std::list<int>::const_iterator itr = myList.begin();
while (true)
{
    int prevValue= *itr;
    std::advance(itr, 1);
    if (itr == myList.end())
    {
        break;
    }
    int diff = prevValue - *itr;
    std::cout << diff << "\n";

}

Upvotes: 1

Gaurav Sehgal
Gaurav Sehgal

Reputation: 7542

You can use std::advance() to get to the next iterator

int x = *itr;
std::list<int>::const_iterator itr2 = itr;
std::advance(itr2,1);
if(itr2==myList.end())
    break;
int y = *(itr2);
int diff = std::abs(x - y);
cout << diff << "\n";

EDIT: If c++ 11 available, see std::next

Upvotes: 1

user4581301
user4581301

Reputation: 33932

You can copy the iterator and run two, but I think it's easier to get the first value outside of the loop and then use the loop to iterate through the second value, resetting the first value with the second before proceeding to the next.

Something like this:

#include <list>
#include <iostream>

int main()
{
    std::list<int> myList;
    myList.push_back(12);
    myList.push_back(15);
    myList.push_back(18);
    myList.push_back(19);
    myList.push_back(25);
    std::list<int>::const_iterator itr = myList.begin();
    if(itr != myList.end()) // is a first value
    {
        int last = *itr; // cache it
        for (itr++; itr != myList.end(); itr++) // get next value
        { 
            int current = *itr; //cache it
            int diff = std::abs(last - current);
            std::cout << diff << "\n";
            last = current; // update last value
        }
    }
    return 0;
}

Upvotes: 1

P0W
P0W

Reputation: 47794

How about using adjacent_difference ?

std::adjacent_difference(myList.begin(), myList.end(), tempList );

See Here


If you're interested in implementation look how its implemented in Possible Implementation section in attached link. All you have to do is replace with list iterator and for output just display on screen, or store it.

Upvotes: 3

user5377926
user5377926

Reputation:

Use increment operator to move iterator.

auto x = itr;
auto y = itr;
if(++y!=myList.end())
{
    int diff = std::abs(*x - *y);
    cout << diff << "\n";
}

Upvotes: 1

Related Questions