Позвольте мне попытаться поддержать вас. Хорошо, что вы все больше и больше знакомитесь с STL.
Итак, вы хотели бы хранить элементы в FIFO, «First In First Out» - контейнере. Вы проверили STL и нашли наиболее подходящую очередь std :: queue. Это именно то, что вам нужно:
- передний
- назад
- 1010 * толчок *
- поп
Итак, вы выбрали 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. Имеет также ваши необходимые функции, например, спереди, сзади. Функции 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;
}
Это решение "more-C ++".
Я надеюсь, что смогу вам немного помочь. , .