Разбор
Для каждого числа будем хранить количество раз , которое он встречается в стеке. В качестве структуры для выберем map.
Объявим массив стеков vector<stack<int>> st
. Здесь хранит элементы, которые встречаются в стеке раз (нумерация ячеек массива начинается с нуля). Порядок, в котором находятся элементы в , соответствуют порядку, в котором они подаются на стек.
Пусть на стек подается число -ый раз. Если элемент не существует, то добавляем (push_back) элемент в массив . Далее на вершину стека кладем .
При удалении следует извлечь элемент с верхушки самого последнего стека.
Например, если в дальнейшем будут только операции pop, то элементы из стека будут удалены в следующем порядке: .
Пример
Рассмотрим порядок занесения элементов в массив стеков для следующего примера.
При удалении элементы будут извлекаться из стека в следующем порядке: .
Реализация алгоритма
Для работы с частотным стеком объявим класс FreqStack.
class FreqStack { public:
Объявим:
отображение , где содержит сколько раз в стеке встречается элемент ;
массив стеков ;
map<int, int> freq; vector<stack<int>> st;
Функция push заносит в стек элемент .
void push(int x) { int f = freq[x]; freq[x] = f + 1; if (f == st.size()) st.push_back(stack<int>()); st[f].push(x); }
Функция pop извлекает из стека элемент.
int pop() { int x = st.back().top(); st.back().pop(); if (st.back().empty()) st.pop_back(); freq[x]--; return x; } };
Основная часть программы. Читаем входные данные. Моделируем работу стека.
while (cin >> str) { if (str == "push") { cin >> n; fs.push(n); } else // pop cout << fs.pop() << endl; }