7

リストを反復しながら、std::list 内の 2 つの連続する要素を比較したいと思います。イテレータが要素 i にあるときに要素 i+1 にアクセスする適切な方法は何ですか? ありがとうコーブ

4

5 に答える 5

12

STL は、連続する 2 つの等しい要素を見つけるために使用できる Context_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 );
于 2008-11-04T10:11:56.557 に答える
10

Boost には、まさにその目的のためにnext(およびその逆の) と呼ばれるユーティリティがあります。prior

*itr == *next(itr)

編集: しかし、一歩戻ってフォレストに目を向けると、本当の問題は、なぜadjacent_find関数をカスタム作成するのかということです。(Nicola Bonelliの回答を受け入れることをお勧めします。)これはSTLの一部であり、コードでBoostを使用しない場合はBoostを使用する必要はありません(これを指摘してくれたコメンターに感謝します)。

于 2008-11-04T08:48:13.013 に答える
8

最も簡単な方法は、2 つの反復子を保持することです (とにかく最後から 2 番目の反復子で停止する必要があるため)。

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)
    {
        //...
    }

は、ループの開始時に soの後増分first初期化され、2 番目の isであることに注意してください。secondfirstlist.begin()list.begin()+1

Chris Jester-Youngは、boost hasnextとfunctions を指摘し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のコメントのおかげで、リストが空の場合のバグを修正しました。
  • への参照を追加しnext、このユースケースに適合しないと思う理由を追加します。
于 2008-11-04T08:57:56.737 に答える
1

List はリバーシブル コンテナーなので、そのイテレーターは双方向イテレーターです。これはフォワード イテレーターのモデルです。これは、これを実行できることを意味していると確信しています (または、オブジェクトの途中から抜け出すことにアレルギーがある場合は、同等のことを行うことができます)。ループなど):

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 を使用するとできます。

于 2008-11-04T12:32:59.500 に答える