0

私はコードをもっている:

it = tableAndHand.begin();
while(++it != tableAndHand.end()) {
 if(*it == *(--it)) {
  ++cardCount;
  ++it;
 } else {
  cardCounts1.insert(pair<int,int>(cardCount,*it));
  while(cardCount > 1) {
   it = tableAndHand.erase(--it);
   --cardCount;
  }
 ++it;
 }
}
cardCounts1.insert(pair<int,int>(cardCount,*(--it)));
while(cardCount > 1) {
 it = tableAndHand.erase(--it);
 --cardCount;
}

tableAndHand は開始時に 7 つの値のリストであり、いくつかの値を消去した後、問題のある場所でセグメンテーション違反が発生します。なぜですか?

リスト内の値はソートされ、リスト {0, 0, 0, 1, 1, 1, 2} のどこかで失敗し、1 を繰り返します (2 つの 0 が正しく消去された後、リストのサイズは既に 5 です)。

一意の値の数をマップ cardCounts1 に保存し、リストから繰り返される値を消去したいだけですが、アルゴリズムの何が問題になっていますか?

編集: 問題は (*it == *(--it)) が左から右に評価されていないように見えますが、cplusplus.com のオペレーターに関する記事やいくつかの記事で「==」の評価が見つかりません。他のサイトでは、左から右に評価されると言われています。それについての良いリンクはありますか?

EDIT2:OK、動作します。tableAndHand.erase(--it)イテレータを割り当てるのを忘れていましたが、完全かつ高速に動作します:)

4

3 に答える 3

3

it最後と比較する前に、ループ内で最大 3 回インクリメントします。

新しいイテレータを保存せずに消去します。

副作用多め。

の順序if(*it == *(--it)) {は定義されていないため、要素をそれ自体と比較することになる場合があります。(==はシーケンス ポイントではないため*it、 and*(--it)はどちらの順序でも評価できます)。

tableAndHand空であることをチェックしません-チェックitする前にインクリメントします。

于 2012-09-17T12:35:50.457 に答える
1

itループの反復ごとに 2 回インクリメントします。

while(++it != tableAndHand.end()) {  // <---- IN THIS LINE
  //HERE IS THE PROBLEM
  if(*it == *(--it)) {
   ++cardCount;
   ++it;      // <----- AND EITHER HERE
  } else {
    cardCounts1.insert(pair<int,int>(cardCount,*it));
    while(cardCount > 1) {
     tableAndHand.erase(--it);
     --cardCount;
    }
    ++it;   // <----- OR HERE
  }
}

つまり、実行する前にリストの最後を超えて実行し、while ループで比較します。

while (++it != tableAndHand.end())

イテレータがコンテナの最後を正確に指すことはないため、永久に true になります。

要素の数が偶数であれば機能する可能性があります (ただし、要素を削除する場合があるため、予測するのは困難です)。


もう 1 つの問題は、最初の反復がすぐにit1 回インクリメントされ、そのコンテナーがたまたま空になった場合にすぐにコンテナーの末尾を超えてプッシュされることです。

于 2012-09-17T12:33:53.213 に答える
1
if(*it == *(--it))

このコードの動作は規定されていません。コンパイラは--it、比較itの左側で評価する前に右側で評価することも、その逆を行うこともできます。

より一般的には、リストの場合、同じ反復子を使用して 2 つの隣接する要素にアクセスしようとしないでください。コードが混乱するだけです。現在の位置とトレーラの 2 つのイテレータを使用し、ループを通過するたびに、それぞれを 1 回だけインクリメントします。

于 2012-09-17T13:09:55.943 に答える