2008-11-04 2 views
5

Я хотел бы сравнить два последовательных элемента в std :: list, итерации по списку. Каков правильный способ доступа к элементу i + 1, в то время как мой итератор находится в элементе i? Благодаря КобСравнение двух последовательных элементов в std :: list

+0

Если возможно, вы можете изменить заголовок вопроса на «Как сравнить два последовательных элемента в std :: list?». Я бы сделал это сам, но у меня нет репутации ;-) – 2008-11-04 10:48:11

ответ

10

подталкивания имеет утилиту next (и ее инверсию, prior) только для этой цели.

*itr == *next(itr) 

Edit: Но, если мы делаем шаг назад, чтобы посмотреть на лес, то реальный вопрос, почему на заказ написать adjacent_find функцию? (Я рекомендую ответить Никола Бонелли, чтобы он был принят.) Это часть STL и не требует использования Boost, если ваш код не использует Boost (спасибо комментаторам за указание на это).

+0

Это весело, как почти каждый вопрос на C++ на сайте имеет совершенно разные «если у вас есть Boost» и «если вы ограничиваете стандартные ответы на C++». Почти как если бы они были разными языками ... – 2008-11-04 12:52:48

+0

Я думал то же самое :) – warren 2008-11-04 13:24:52

+0

Это _is_ как разные языки! Boost - это то, что делает C++ полезным для меня. : -P Не использовать Boost, как не использовать SRFI при написании кода схемы. :-P – 2008-11-04 20:48:37

8

Простейшим способом было бы провести два итератора (так как вам все равно придется останавливаться на предпоследнем).

std::list<int>::const_iterator second = list.begin(), 
           end = list.end(); 

if (second != end) // Treat empty list 
    for(std::list<int>::const_iterator first = second++; // Post-increment 
     second != end; 
     ++first, ++second) 
    { 
     //... 
    } 

Обратите внимание, что first инициализируется с post-incrementation из second так что, когда начинается цикл first является list.begin() и второе list.begin()+1.

Chris Jester-Young points out, что повышение имеет next и prior функции, хотя я не знаком с этими функциями (за мои грехи) их реализации тривиальна (особенно если учесть, что list имеет двунаправленные итераторы).

template <class Iterator> 
Iterator next(Iterator i) // Call by value, original is not changed 
{ 
    return ++i; 
} 
// Implementing prior is left as an exercise to the reader ;o) 

У меня такое ощущение, что использование next не номера этой проблемы, а также поддерживать как итераторы, так как вы должны помнить, чтобы убедиться, что next(i) не равна end() при каждом использовании.


редактирует:

  • Исправлена ​​ошибка, если список пуст благодаря комментарий Luc Touraille «s.
  • Добавить ссылку на next и почему я думаю, что он не подходит для этого прецедента.
10

STL предоставляет алгоритм adj_find(), который может использоваться для поиска двух последовательных равных элементов. Существует также версия с пользовательским предикатом.

Эти прототипы:

template <class ForwardIterator> 
    ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last); 

template <class ForwardIterator, class BinaryPredicate> 
    ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last, 
            BinaryPredicate pred); 
1

Список является обратимым Контейнер, поэтому его итераторы двунаправленные итераторы, который представляет собой модель Forward итератора, который я уверен, что означает, что вы можете сделать это (или что-то эквивалент, если у вас аллергия на вырывался из середины петли и т.д.):

if (!l.empty()) { 
    for (list<T>::const_iterator i = l.begin();;) { 
     const T &a = *i; 
     ++i; 
     if (i == l.end()) break; 
     do_comparison(a, *i); 
    } 
} 

вы не могли бы сделать это с помощью итератора ввода, потому что с теми, что только значение «существовать» до тех пор, так как у вас есть итератор. Но вы можете с помощью Forward Iterator.

0
for (list<int>::iterator it = test.begin(); it!=test.end(); it++) { 
     cout<<*it<<":\t"; 
     list<int>::iterator copy = it; 
     for(list<int>::iterator it2 = ++copy; it2!=test.end();it2++){ 
      cout<<*it2<<"\t"; 
     } 
     cout<<endl; 
    } 
Смежные вопросы