8

を反復しようとしてstd::listいますが、問題があります。反復中に実行される操作によって、リストから要素が追加または削除される可能性があります。この場合、追加は問題になりませんが、削除すると、シーケンス内の現在または次のアイテムを含むリスト内のイテレータが無効になる可能性があります。

リストを変更する決定が行われるポイントは、反復ループから遠く離れています。デバッガーは、2 つの呼び出しスタックで 40 の関数呼び出しを示しています。そのため、削除に基づいてイテレータを変更することはできません。

私が考えることができる唯一のことは、最初にリストのコピーを作成し、それを繰り返し、各要素をテストしてマスターリストに残っていることを確認することです. これは、可能であれば避けたい O(n^2) 命題です。

4

4 に答える 4

1

リスト内のイテレータを無効にする可能性があります

なにもない。

の説明を見てくださいstd::list::erase

イテレータの有効性

  • 関数によって削除された要素を参照する反復子、ポインター、および参照は無効になります。
  • 他のすべての反復子、ポインター、および参照は、その有効性を維持します

消去の結論: 削除された要素のみが無効になります。その他はすべて有効です。そして、この場合、ほとんどのコンテキストで O(n) を実装する機会があります。

于 2013-06-10T23:05:42.860 に答える
0

(リストのコピーを作成することに加えて) 2 つの可能なアプローチが思い浮かびます。

1) すぐにリストから削除しないでください。代わりに、イテレータの別のコンテナを構築して、完全なイテレーションがすべて完了したら消去します。これは動作を変更します (「削除された」要素は引き続き処理される可能性があります) ので、それが役立つかどうかはわかりません。

2) リストにポインターまたはアイテム/有効性フラグとのペアのいずれかを含め、有効性を単純にクリアします。次に、最初の反復が完了したら、リタイアしたノードをクリーンアップする反復をもう一度実行します。

于 2013-06-11T00:05:45.390 に答える