Будет проще, если вы используете постфикс вместо префикса.См. Обратная польская запись (RPN) .Учитывая выражение в RPN, легко оценить это, используя только один стек.
Но так как вы попросили способ вычисления выражений prefix без рекурсии и использования стеков (для, возможно, более простого)кстати, см. РЕДАКТИРОВАТЬ: ниже), вот один из способов:
Мы можем сделать это, используя два стека.
Один стек (назовите его Evaluation) содержит операторы (например, +, sin и т. д.)и операнды (например, 3,4 и т. д.), а другой стек (назовите его Count) содержит кортеж из числа оставшихся видимых операндов + количество операндов, ожидаемых оператором.
Каждый раз, когда вы видите операторвы помещаете оператор в стек оценки и помещаете соответствующий кортеж в стек счета.
Каждый раз, когда вы видите операнд (например, 3,5 и т. д.), вы проверяете верхний кортеж из стека счета и уменьшаетеколичество операндов, оставшихся для просмотра в этом кортеже.
Если количество операндов, оставшихся для просмотра, станет равным нулю, вы выталкиваете кортеж из стека подсчета.Затем из стека оценки вы получаете необходимое количество операндов (вы знаете это из-за другого значения кортежа), извлекаете оператор и выполняете операцию, чтобы получить новое значение (или операнд).
Теперь поместите новый операнд обратно в стек оценки.Этот новый толчок операнда заставляет вас еще раз взглянуть на вершину стека Count, и вы делаете то же самое, что мы только что сделали (уменьшаем количество увиденных операндов, сравниваем с нулем и т. Д.).
Если число операндов нестановясь нулем, вы переходите к следующему токену на входе.
Например, скажем, вы должны были оценить + 3 + 4/20 4
Стеки будут выглядеть так (слева вверхустек)
Count Evaluation Input
+ 3 + 4 / 20 4
(2,2) + 3 + 4 / 20 4
(2,1) 3 + + 4 / 20 4
(2,2) (2,1) + 3 + 4 / 20 4
(2,1) (2,1) 4 + 3 + / 20 4
(2,2) (2,1) (2,1) / 4 + 3 + 20 4
(2,1) (2,1) (2,1) 20 / 4 + 3 + 4
(2,0) (2,1) (2,1) 4 8 / 4 + 3 +
Since it has become zero, you pop off two operands, the operator /
and evaluate and push back 5. You pop off (2,0) from the Count stack.
(2,1) (2,1) 5 4 + 3 +
Pushing back you decrement the current Count stack top.
(2,0) (2,1) 5 4 + 3 +
Since it has become zero, you pop off 5,4 and + and evaluate and push back 9.
Also pop off (2,0) from the count stack.
(2,0) 9 3 +
12
РЕДАКТИРОВАТЬ:
Друг предложил способ сделать это без нескольких стеков:
Начните с конца, перейдите к первому оператору.Токены справа от этого будут операндами.Оценить и повторить.Кажется, намного проще, чем делать это с двумя стеками.Мы можем использовать двусвязный список для представления входных данных, которые мы изменяем во время обработки.Когда вы оцениваете, вы удаляете узлы, а затем вставляете результат.Или вы могли бы просто использовать один стек.