c++ - STL中struct类型的迭代队列

标签 c++ c++11 stl queue

我有一个结构类型队列的简单示例。 这是极客链接: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 或 queue[i].depend?请帮助我,因为我不知道正确的语法。 对于上面的代码输入:

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

输出:队列大小为:4

这是极客链接:https://ide.geeksforgeeks.org/PDvXlup2Z6

最佳答案

让我尽力支持你。很高兴您对 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 个空任务的 vector 。

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

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

这样你就可以消除 3 个临时变量:id、day、dep 此外,您还可以删除 w 和 j。不需要它们。

下一步:类或结构知道应如何读取(或写入)其值。因此,您将为您的类任务重载 >> 运算符。这样一来,您的类(class)开始将如下所示:

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。你在问:

Iterating queue of struct type in stl

答案是:不可能。

std::queue 没有迭代器,也没有索引运算符 []。原因是 std::queue 是不同 STL 容器的包装器。 std::queue 的目的是隐藏它的“内部”值并只允许访问 front 和 back。这对于您的正常用途来说是可以的,但对于您希望在调试情况下访问“内部”成员而言则不行。解决方法很简单。选择一个不同的容器,在这种情况下,为了您的目的,选择一个 std::deque。也有你需要的功能,例如前后。 push 和 pop 函数有扩展名,因为有 pop_front 和 pop_back 以及 psuh_front 和 push_back。而且,这就是重点,它有迭代器和索引运算符 []。现在你可以像这样制作你的程序了:

#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++”解决方案。

我希望我能帮到你一点点。 . .

关于c++ - STL中struct类型的迭代队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56607863/

相关文章:

c++ - 了解 C++ 转换运算符的选择

c++ - 如何正确调用模板函数?

c++ - map::iterator 是否产生左值?

c++ - std::string 是 STL 的一部分吗?

C++ - STD 正则表达式在长多行匹配期间在 MSVC 中崩溃

c++ - 事件(线程)可以持续多长时间

c++ - 包含库时找不到 Qt shared_ptr

c++ - 如何将变量传递给 std::async?

c++ - OpenCV - 将 vector 的 vector 转换为 Mat

c++ - Visual Studio 9 : Display Linker Search Paths