2

stdin から次の入力を取得します。

2
5
2 1 5 3 4
5
2 5 1 3 4

最初の行はキューの数を表します (この値を と呼びましょうn)。次に、各キューの最初の行にlキューの長さを示す値があり、その後に実際のキューが続きます。

istream_iterator次のようにを使用して、キューをベクトルに入れようとしています。

using namespace std;
int n{};
int l{};
typedef std::istream_iterator<int> input_iterator;
cin >> n;
cout<< "n: " << n << "\n";
for(int i = 0; i < n ; ++i){

    cin >> l;
    cout << "l: " << l << "\n";
    std::vector<int> queue;
    int counter = 0;
    for (input_iterator it(cin); counter < l && it != input_iterator(); ++it){
        queue.push_back((*it));
        ++counter;
    }
    cout<< "Queue: ";
    std::copy(queue.begin(), queue.end(), 
                  std::ostream_iterator<int>(std::cout, " "));
    cout << "\n";
}

このコードは、次の出力を生成します。

n: 2
l: 5
Queue: 2 1 5 3 4 
l: 2
Queue: 5 1 

ご覧のとおり、最初のキューは正しく読み取られています。しかし、2 番目はではなくlであるべきです。52

に何が起こってい5ますか? イテレータによって消費されますか?どこでエラーをしましたか?

4

3 に答える 3

2

ループは基本的forに単なるファンシーwhileループです。

forあなたのコードからこのループを取りましょう:

for (input_iterator it(cin); counter < l && it != input_iterator(); ++i){
    queue.push_back((*it));
    ++counter;
}

これは次と同等です。

{
    input_iterator it(cin);
    while (counter < l && it != input_iterator())
    {
        queue.push_back((*it));
        ++counter;
        ++it;
    }
}

ループの最後の行である++it;ステートメントに注目してください。それがあなたの問題の原因です。イテレータが多すぎると増加するため、ループの後、イテレータは5入力でを読み取ります。ループの後の次の入力操作で2は、次の行の が読み取られます。

1 つの解決策は、反復子を保持し、外側のループ内で再利用することです。おそらく、すべての入力に使用します。

私のコメントでほのめかした別の解決策は、forゼロからl のみにループし、イテレータをまったく使用せず、プレーンのみを使用することcin >> ...です。

于 2016-11-18T09:43:29.867 に答える
2

問題は、for ループがiキューの最後の要素の次の位置にあることです。したがってoperator>>、 の次の値を取得するために呼び出すとl、1 つの「読み取りステップ」が遠すぎます。

iこの問題を回避するには、すべての読み取り操作に同じ反復子を使用し、次のように名前を変更して、外側のループ内の変数との名前の衝突を回避します。

using namespace std;
int n{};
int l{};
typedef std::istream_iterator<int> input_iterator;
cin >> n;
cout<< "n: " << n << "\n";
input_iterator it(cin);
for(int i = 0; i < n ; ++i){

    l = *(it++);
    cout << "l: " << l << "\n";
    std::vector<int> queue;
    int counter = 0;
    while( counter < l && it != input_iterator() ){
        queue.push_back(*(it++));
        ++counter;
    }
    cout<< "Queue: ";
    std::copy(queue.begin(), queue.end(), 
                  std::ostream_iterator<int>(std::cout, " "));
    cout << "\n";
}
于 2016-11-18T09:41:22.683 に答える
2

IANALL、しかし istream_iterator は、私の知る限り、そのoperator++(). 読み取るすべてのグループ (数値の行) に対して istream イテレーターを再作成しているため、入力ストリームから次の整数を既に読み取ったイテレーターを破棄しています。

1 つの解決策は、入力反復子を for ループの外で 1 回だけ作成し、それを全体で使用することです。

于 2016-11-18T09:37:30.347 に答える