标准输入迭代器问题

时间:2016-09-05 04:56:26

标签: c++ stl

这是我解决其中一个黑客问题的代码。简而言之,我正在阅读每个测试的输入,解决并输出它。由于某种原因,它没有在基于t

的for循环的第二次迭代中正确读取m的值
#include <vector>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <numeric>
#include <unordered_map>

using namespace std;

int main() {
    bool debug = true;

    istream_iterator<int> iit(cin);
    int tests = *(iit++);

    for (int t = 0; t < tests; t++) {
        int m = *(iit++);
        int n = *(iit++);

        vector<int> ele; ele.reserve(n);
        copy_n(iit, n, back_inserter(ele));

        if (debug) {
            cout << "M: " << m << ", N: " << n << ", Elements: ";
            copy(ele.begin(), ele.end(), ostream_iterator<int> (cout, " "));
            cout << endl;
        }


        unordered_map<int, int> map;
        for (int index = 0; index < n; index++) {
            map[ele[index]] = index;
        }

        bool found = false;
        for (int index = 0; index < n; index++) {
            auto robber = m - ele[index];
            auto search_iterator = map.find(robber);
            if (search_iterator != map.end()) {
                int I = index + 1;
                int J = search_iterator->second + 1;
                cout << I << " " << J << endl;
                found = true;
                break;
            }
        }

        if (debug && !found) {
            cout << "Not found" << endl;
        }
    }

    return 0;
}

这是输入和输出

04:47:20 vagrant@vm ~/cpp/icecream_parlor $ cat input.txt
2
4
5
1 4 5 3 2
4
4
2 2 4 3
04:52:49 vagrant@vm ~/cpp/icecream_parlor $ g++-4.9 -std=c++14 main.cpp -o app && ./app < input.txt
M: 4, N: 5, Elements: 1 4 5 3 2
1 4
M: 1, N: 4, Elements: 4 2 2 4
Not found
04:52:51 vagrant@vm ~/cpp/icecream_parlor $

1 个答案:

答案 0 :(得分:0)

与普通迭代器不同,流迭代器的行为略有不同。 流迭代器绑定到某个I / O流,并且迭代器的副本仍然绑定到同一个流。

因此它违反了纯值语义,类似于智能指针的工作方式,但由于它具有迭代器接口,因此违规行为不是很明显。

当您调用copy_n时,您按值传递了迭代器iit,当函数退出时,iit未更改其内部簿记状态,但基础流{{1}已经发生变异,因为当cin递增迭代器的副本时,流在内部向前搜索。

这个问题是违反合同的结果,当你从它们读取或增加它们时,迭代器不会改变它们指向的容器。

我多次使用流迭代器,我从未遇到过这个怪癖,因为我在调用copy_n之后从未重用过流迭代器。

我认为必须记住,这可能会发生,并且在将它们传递给库函数后再也不要重用流迭代器。

在没有破坏适用于流迭代器的现有代码的情况下,我想不出用语言解决这个问题的方法。