リストを反復しながら、std::list 内の 2 つの連続する要素を比較したいと思います。イテレータが要素 i にあるときに要素 i+1 にアクセスする適切な方法は何ですか? ありがとうコーブ
5 に答える
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 );
Boost には、まさにその目的のためにnext
(およびその逆の) と呼ばれるユーティリティがあります。prior
*itr == *next(itr)
編集: しかし、一歩戻ってフォレストに目を向けると、本当の問題は、なぜadjacent_find
関数をカスタム作成するのかということです。(Nicola Bonelliの回答を受け入れることをお勧めします。)これはSTLの一部であり、コードでBoostを使用しない場合はBoostを使用する必要はありません(これを指摘してくれたコメンターに感謝します)。
最も簡単な方法は、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であることに注意してください。second
first
list.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
、このユースケースに適合しないと思う理由を追加します。
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 を使用するとできます。