Задача. Простой дек
Реализуйте структуру данных «дек». Напишите программу, содержащую описание дека и моделирующую работу дека, реализовав все указанные здесь методы. Программа считывает последовательность команд и в зависимости от команды выполняет ту или иную операцию. После выполнения каждой команды программа должна вывести одну строчку. Возможные команды для программы:
push_front
Добавить (положить) в начало дека новый элемент. Программа должна вывести ok.
push_back
Добавить (положить) в конец дека новый элемент. Программа должна вывести ok.
pop_front
Извлечь из дека первый элемент. Программа должна вывести его значение.
pop_back
Извлечь из дека последний элемент. Программа должна вывести его значение.
front
Узнать значение первого элемента (не удаляя его). Программа должна вывести его значение.
back
Узнать значение последнего элемента (не удаляя его). Программа должна вывести его значение.
size
Вывести количество элементов в деке.
clear
Очистить дек (удалить из него все элементы) и вывести ok.
exit
Программа должна вывести bye и завершить работу.
Гарантируется, что количество элементов в деке в любой момент не превосходит 100. Все операции:
- pop_front
- pop_back
- front
- back
всегда корректны.
Объяснение: Количество элементов во всех структурах данных не превышает 10000, если это не указано особо.
Тесты
№ | Входные данные | Выходные данные |
1 |
push_back 3 push_back 14 size clear push_front 1 back push_back 2 front pop_back size pop_front size exit |
ok
ok 2 ok ok 1 ok 1 2 1 1 0 bye |
2 | size
push_back 8 push_front 4 size front back push_back 3 pop_front front pop_back back exit |
0
ok ok 2 4 8 ok 4 8 3 8 bye |
Решение
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
#include <iostream> #include <vector> #include <string> using namespace std; struct Deque { vector<int> box1; vector<int> box2; int n, box_size=0; void push_front(int n) { box1.push_back(n); box_size++; } void push_back(int n) { box2.push_back(n); box_size++; } int pop_front() { if(box1.size()>0) { int a=box1[box1.size()-1]; box1.erase(box1.end()-1); box_size--; return a; } else if(box2.size()>0) { int a=box2[0]; box2.erase(box2.begin()); box_size--; return a; } return 1; } int pop_back() { if(box2.size()>0) { int a=box2[box2.size()-1]; box2.erase(box2.end()-1); box_size--; return a; } else if(box1.size()>0) { int a=box1[0]; box1.erase(box1.begin()); box_size--; return a; } return 1; } int front() { if(box1.size()>0) { int a=box1[box1.size()-1]; return a; } else if(box2.size()>0) { int a=box2[0]; return a; } return 1; } int back() { if(box2.size()>0) { int a=box2[box2.size()-1]; return a; } else if(box1.size()>0) { int a=box1[0]; return a; } return 1; } int size() { return box_size; } string clear() { box1.erase(box1.begin(), box1.end()); box2.erase(box2.begin(), box2.end()); box_size=0; return "ok"; } string exit() { return "bye"; } }; int main() { Deque a; string s; while(cin>>s) { if(s=="push_front") { int n; cin>>n; a.push_front(n); cout<<"ok"<<endl; } if(s=="push_back") { int n; cin>>n; a.push_back(n); cout<<"ok"<<endl; } if(s=="pop_front") { cout<<a.pop_front()<<endl; } if(s=="pop_back") { cout<<a.pop_back()<<endl; } if(s=="front") { cout<<a.front()<<endl; } if(s=="back") { cout<<a.back()<<endl; } if(s=="size") { cout<<a.size()<<endl; } if(s=="clear"){ a.clear(); cout<<a.clear()<<endl; } if(s=="exit") { cout<<a.exit()<<endl; break; } } return 0; } |
Алгоритм решения
Реализация двусторонней очереди идет посредством векторов [latex]box1[/latex] и [latex]box2[/latex], поэтому нет необходимости делать проверку на переполнение. Команды [latex]push_front[/latex] и [latex]push_back[/latex] соответственно добавляют в концы векторов [latex]box1[/latex] и [latex]box2[/latex] элементы и увеличивают размер дека box_size (на единицу за каждый добавленный элемент). Рассмотрим команду [latex]front[/latex]. Проверяя присутствие элементов в [latex]box1[/latex] мы выводим последний элемент вектора, так как добавляли элемент с помощью [latex]push_front[/latex] в конец вектора [latex]box1[/latex]. Если же вектор [latex]box1[/latex] пуст, то выводим первый элемент вектора [latex]box2[/latex], который в случае пустого вектора [latex]box1[/latex] является первым элементом дека. Команда [latex]back[/latex] относительно [latex]front[/latex] с векторами работает инверсивно. Т.е. Проверяя присутствие элементов в [latex]box2[/latex] выводим последний элемент данного вектора. Если же вектор [latex]box2[/latex] пуст, то выводим первый элемент вектора [latex]box1[/latex] , который в случае пустого вектора [latex]box2[/latex] является последним элементом дека. С командами [latex]pop_front[/latex] и [latex]pop_back[/latex] работают идентично [latex]front[/latex] и [latex]back[/latex]. Отличие лишь в том, что команды [latex]pop[/latex] в дополнении к выводу элемента удаляют его, уменьшая размер дека [latex]box_size[/latex] (на единицу за каждый удаленный элемент). Команда [latex]size[/latex] выводит размер дека [latex]box_size[/latex]. Команда clear удаляет все элементы векторов [latex]box1[/latex], [latex]box2[/latex] и обнуляет размер дека. Команда [latex]exit[/latex] выводит «bye» и завершает работу программы. Команды принимаются из потока ввода посредством строки s.
Ссылка на код.
А в чем смысл введения двух векторов? Если бы удалось всегда добавлять и удалять с конца, то было бы очень эффективно. Но при опустошении одного вектора всё равно приходится извлекать элементы из начала второго.
Тогда зачем?
Т.е. как упражнение я зачёл, но как творческую находку оценить пока не смог 🙁