Será más simple si usa postfix en lugar del prefijo. Ver Reverse Polish Notation (RPN). Dada una expresión en RPN, es fácil evaluar eso usando solo una pila.
Pero ya que pedirá una forma de evaluar prefijo expresiones sin recursividad y el uso de pilas (por ser un medio más simple, consulte Edición: abajo), aquí es una manera:
Podemos hacer esto utilizando dos pilas.
Una pila (llámala Evaluación) contiene los operadores (como +, sin, etc.) y operandos (como 3,4, etc.) y la otra pila (llámala Cuenta) contiene una tupla del número de operandos restantes. visto + la cantidad de operandos que espera un operador.
Cada vez que vea un operador, empujará al operador hacia la pila de evaluación y colocará la tupla correspondiente en la pila de conteo.
Cada vez que vea un operando (como 3,5, etc.), compruebe la tupla superior de la pila de recuento y disminuya el número de operandos que quedan para verse en esa tupla.
Si el número de operandos que quedan por ver se convierte en cero, saca la tupla de la pila de recuento. Luego, desde la pila de evaluación, extraes la cantidad de operandos necesarios (lo sabes por el otro valor de la tupla), desconectas el operador y realizas la operación para obtener un nuevo valor (o operando).
Ahora vuelva a colocar el nuevo operando en la pila de evaluación. Este nuevo impulso de operando hace que eche otro vistazo a la parte superior de la pila de recuento y hace lo mismo que acabamos de hacer (disminuir los operandos vistos, comparar con cero, etc.).
Si el recuento de operandos no se convierte en cero, continúe con el siguiente token en la entrada.
Por ejemplo decir que había que evaluar + 3 + 4/20 4
Las pilas se verá como (izquierda es la parte superior de la pila)
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
EDIT:
Un amigo sugirió una forma de hacerlo sin múltiples pilas:
Comience desde el final, vaya al primer operador. Los tokens a la derecha de eso serán operandos. Evaluar y rehacer Parece mucho más simple que hacerlo con dos pilas. Podemos usar una lista doblemente vinculada para representar la entrada que cambiamos durante el procesamiento. Cuando evalúa, elimina nodos y luego inserta el resultado. O tal vez podrías simplemente usar una pila.
¿Es esta tarea? –
¿por qué necesitas paréntesis entonces? – Andrey
Si se puede expresar con recursión, se puede expresar con una pila. – KLee1