2017-12-17 15 views
0

私は2017 Advent of Codeのパズルを解いていました。特定のアルゴリズムを使用して循環バッファを埋める必要がありました。バッファの実装のために、私は最初にvectorを使い、次にdequeで試しました。ベクトルとキューの値を出力するとき、私は別の結果を得ています。ここでは、コードです:ベクトルを使用しているときstd :: vectorの挿入とstd :: dequeの挿入

#include <iostream> 
#include <vector> 

void PrintBuffer(std::vector<int> a_CircularBuffer) 
{ 
    for (std::vector<int>::iterator it = a_CircularBuffer.begin(); it != a_CircularBuffer.end(); ++it) { 
     std::cout << *it << " "; 
    } 
    std::cout << std::endl; 
} 

int main() 
{ 
    std::vector<int> circularBuffer; 
    circularBuffer.reserve(20); 

    circularBuffer.push_back(0); 
    circularBuffer.push_back(1); 

    std::vector<int>::iterator currentPosition = circularBuffer.begin() + 1; 

    for (int i = 2; i < 20; ++i) { 
     int steps = 378; 
     if (steps >= i) { 
      steps = (steps % i); 
     }  

     if ((circularBuffer.end() - currentPosition) <= steps) { 
      currentPosition = circularBuffer.begin() + (((currentPosition - circularBuffer.begin()) + steps) % i); 
      circularBuffer.insert(currentPosition, i); 
     } 
     else { 
      currentPosition = currentPosition + steps; 
      circularBuffer.insert(currentPosition, i); 
     } 
     PrintBuffer(circularBuffer); 
    } 
    return 0; 
} 

は、これが結果です:

0 2 1 
0 3 2 1 
0 3 2 4 1 
0 5 3 2 4 1 
0 6 5 3 2 4 1 
0 7 6 5 3 2 4 1 
0 7 6 8 5 3 2 4 1 
0 7 6 9 8 5 3 2 4 1 
0 10 7 6 9 8 5 3 2 4 1 
0 10 7 6 9 11 8 5 3 2 4 1 
0 10 7 6 9 11 8 5 3 2 4 12 1 
0 10 7 6 9 11 8 5 3 2 4 12 13 1 
0 10 7 6 9 11 8 5 3 2 4 12 14 13 1 
15 0 10 7 6 9 11 8 5 3 2 4 12 14 13 1 
... 

と両端キューを使用している場合、これは(ちょうど「デック」に「ベクター」に変更し、circularBuffer.reserveをコメントアウトである(20 )行):

0 2 1 
0 3 2 1 
0 3 2 4 1 
0 5 3 2 4 1 
0 5 6 3 2 4 1 
0 5 6 7 3 2 4 1 
0 5 6 7 3 8 2 4 1 
0 5 6 7 3 9 8 2 4 1 
0 5 6 10 7 3 9 8 2 4 1 
0 5 6 10 7 3 9 8 11 2 4 1 
0 5 12 6 10 7 3 9 8 11 2 4 1 
0 5 12 6 13 10 7 3 9 8 11 2 4 1 
0 5 12 6 13 14 10 7 3 9 8 11 2 4 1 
0 5 12 6 13 14 10 7 3 15 9 8 11 2 4 1 
... 

ベクターとデキューの結果が異なるのはなぜですか?

答えて

1

再割り振りの原因となる要素を挿入し、古いイテレータを再度使用すると、未定義の動作が発生します。

何かが起こる可能性があります。

インデックスを使用して現在位置を保存すると、同じように動作します。

+0

ありがとうございました。はい、後で私は現在の位置を格納するためにインデックスを使用していました。デッキとイテレータと同じように機能しました。なぜベクトルが違うのか、私はそれが未定義の振る舞いであることを知らなかったのです。また、私はこのような何かを行うときcurrentPosition = circularBuffer.insert(currentPosition、私)、私は以前と同じ結果を得ています。私はこれがcurrentPositionイテレータを "更新"すると考えました。 – adamm

+0

さらにもう1つ、十分なスペースを確保していれば、再割り当てはできません。その後、イテレータはOKになるはずですか? – adamm

+0

再割り当てされていなくてもUBを継承しない>シーケンスの最初または最後に挿入が行われた場合、このコンテナに関連するすべてのイテレータは無効になりますが、ポインタと参照は参照元と同じ要素を参照して有効です。コールの前に 挿入が両端キュー内の他の場所で行われる場合、このコンテナに関連するすべてのイテレータ、ポインタ、および参照は無効になります。 – RiaD

関連する問題