在stl中迭代结构类型的队列

时间:2019-06-15 06:17:22

标签: c++ c++11 stl queue

我有一个简单的结构类型队列的例子。 这是怪胎ide链接:https://ide.geeksforgeeks.org/PDvXlup2Z6

#include<bits/stdc++.h>
using namespace std;

struct Task{
    int pid;
    int days;
    int depend;
};

int main()
{
    int w,i,j,t,id,day,dep;
    cin>>t;
    Task task[t];
    for(i=0;i<t;i++)
    {
        cin>>id>>day>>dep;
        task[i].pid=id;
        task[i].days=day;
        task[i].depend=dep;
    }
    //for(i=0;i<t;i++)
    //cout<<task[i].pid<<" "<<task[i].days<<" "<<task[i].depend<<endl;

    queue<Task> job_queue;
    //queue<struct Task>::iterator it;

    for(i=0;i<t;i++)
        job_queue.push(task[i]);

    cout<<"Queue size is: "<<job_queue.size()<<endl;
    /*for(auto it = job_queue.begin();it!=job_queue.end();it++)
    {
        cout<<*it->pid<<endl;
    }*/
    return 0;
}

我在迭代队列中要打印其所有元素时遇到问题,还应该如何处理队列内容的特定元素,例如queue[i].id or queue[i].depend?请帮助我,因为我不知道正确的语法。 对于上面的代码输入:

4
1 2 0
2 4 1
3 7 0
4 12 1

输出:队列大小为:4

这是怪胎ide链接:https://ide.geeksforgeeks.org/PDvXlup2Z6

2 个答案:

答案 0 :(得分:1)

最后,我找到了解决方案:

for(i=0;i<t;i++)
        job_queue.push(task[i]);

    auto iter=0;
    int size =job_queue.size();
    Task temp;
    while(iter++ <size)
    {
        temp=job_queue.front();
        cout<<"Entry "<< temp.pid<<" "<<temp.days<<" "<<" "<<temp.depend<<endl;
        job_queue.pop();
        job_queue.push(temp);
    }

答案 1 :(得分:1)

让我尝试支持您。很好,您越来越熟悉STL。

因此,您想将元素存储在FIFO中,即“先进先出”容器。您检查了STL,发现std :: queue最合适。它正是您需要的:

  • 前面
  • 返回
  • 流行

因此,您选择了std :: queue作为元素“任务”的容器。现在,查看您的代码,可以使用现代C ++程序进行几个改进步骤。

首先,我们需要消除C ++语法(和语义)错误。在C ++中,您无法定义动态纯数组。数组的维数必须是编译时间常数。因此,真正的C ++编译器不会吃

Task task[t];

但是幸运的是C ++的容器的行为类似于普通数组,但是可以动态增长:std :: vector。您应该首选std :: vector(或其他容器)而不是普通数组。结果是:

std::vector<Task> task(t);

这将创建一个包含t个空任务的向量。

下一个优化是删除临时变量。在输入循环中,您可以编写:

cin >> task[i].pid >> task[i].days >> task[i].depend;

因此,您可以消除3个临时变量:id,day,dep 并且,您还可以删除w和j。不需要它们。

下一步:类或结构知道如何读取(或写入)其值。因此,您将为类Task重载>>运算符。这样,您的课程开始将看起来像这样:

struct Task {
    int pid;
    int days;
    int depend;
    friend istream& operator>>(istream& is, Task& task) { return is >> task.pid >> task.days >> task.depend;  }
};

int main()
{
    int t, i;
    cin >> t;
    std::vector<Task> task(t);
    for (i = 0; i < t; i++)
    {
        cin >> task[i];
    }

    . . . . 

已经好多了。现在是下一个主要问题以及您问题的答案。为了进行调试,您想遍历job_queue。你在问:

  

在stl中迭代结构类型的队列

答案是:不可能。

std :: queue没有迭代器,也没有索引运算符[]。这样做的原因是std :: queue是另一个STL容器的包装。 std :: queue的意图是隐藏其“内部”值,并仅允许访问正面和背面。出于您的正常目的,这是可以的,但对于在调试情况下访问“内部”成员的愿望,则不是。解决方案很简单。选择一个不同的容器,在这种情况下(出于您的目的),选择一个std :: deque。还有您所需的功能,例如前后。由于存在pop_front和pop_back以及psuh_front和push_back,所以push和pop函数具有扩展名。重点在于,它具有迭代器和索引运算符[]。现在,您可以像这样制作程序了:

#include <iostream>
#include <vector>
#include <deque>

using namespace std;

struct Task {
    int pid;
    int days;
    int depend;
    friend istream& operator>>(istream& is, Task& task) { return is >> task.pid >> task.days >> task.depend; }
    friend ostream& operator<<(ostream& os, const Task& task) { return os << task.pid << ' ' << task.days << ' ' << task.depend; }
};

int main()
{
    int t, i;
    cin >> t;
    std::vector<Task> task(t);
    for (i = 0; i < t; i++)
    {
        cin >> task[i];
    }
    deque<Task> job_queue;
    for (i = 0; i < t; i++)
        job_queue.push_back(task[i]);

    cout << "Queue size is: " << job_queue.size() << endl;
    // Option 1
    for (i = 0; i < t; ++i) {
        cout << task[i] << '\n';
    }
    // Option 2, more C++
    for (auto it = job_queue.begin(); it!=job_queue.end(); ++it){
        cout << *it << '\n';
    }
    // Or, even better, taking C++ range based for
    for (const auto& taskref : job_queue) {
        cout << taskref  << '\n';
    }
    return 0;
}

但这还没有结束。在C ++中,您可以对所有内容使用算法。对于输入和输出,您尤其可以使用std :: istream_iterator和std :: ostream:iterator和std :: copy函数。

这样,这也许是最终的优化,您的程序如下所示:

#include <iostream>
#include <vector>
#include <deque>
#include <algorithm>
#include <iterator>

struct Task {
    int pid;
    int days;
    int depend;
    friend std::istream& operator>>(std::istream& is, Task& task) { return is >> task.pid >> task.days >> task.depend; }
    friend std::ostream& operator<<(std::ostream& os, const Task& task) { return os << task.pid << ' ' << task.days << ' ' << task.depend; }
};

int main()
{
    int numberOfTasks{ 0 };
    std::deque<Task> jobQueue{};

    std::cin >> numberOfTasks;

    // Read all task values
    std::copy_n(std::istream_iterator<Task>(std::cin), numberOfTasks, std::back_inserter(jobQueue));

    // For Debug purposes. Print job Queue
    std::copy(jobQueue.begin(), jobQueue.end(), std::ostream_iterator<Task>(std::cout, "\n"));

    return 0;
}

那是“更多C ++”解决方案。

希望我能对您有所帮助。 。