2

我从标准输入得到以下输入:

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

第一行代表队列的数量(我们称之为 value 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 

如您所见,第一个队列已正确读取。但第二个l应该是5,不是2

发生了5什么?它被迭代器消耗了吗?我在哪里犯了错误?

4

3 回答 3

2

IANALL,但据我所知 istream_iterator 允许在其operator++(). 由于您正在为您读取的每个组(数字行)重新创建一个 istream 迭代器,因此您正在丢弃一个已经从输入流中读取下一个整数的迭代器。

一种解决方案是在 for 循环之外只创建一次输入迭代器并在整个过程中使用它。

于 2016-11-18T09:37:30.347 回答
2

您的问题是您的 for 循环i位于队列最后一个元素旁边的位置。因此,当调用operator>>获取 的下一个值时l,您是一个“阅读步骤”太远了。

为避免该问题,您可以对所有读取操作使用相同的迭代器 - 并重命名它以避免与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

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在下一行中读取。

一种解决方案是保留迭代器,并在外循环中重用它。也许将它用于所有输入。

我在评论中暗示的另一个解决方案是让for循环从零到l only并且根本不使用迭代器,而只使用 plain cin >> ...

于 2016-11-18T09:43:29.867 回答