[C con Clase] operaciones combinadas en c

Gilberto Cuba Ricardo gilbert en hlg.rimed.cu
Jue Mayo 13 16:25:46 CEST 2010


estudiante escribió:

> gracias a todos por las sugerencias
> bueno gilberto lo que me dices haber si entendi es colocar los
> signos en una pila de acuerdo a su precedencia

Bueno, básicamente es eso para la conversión de la notación infija a
la postfija, que es donde nos quitamos de encima el dolor de cabeza de
la precedencia de los operadores y de los paréntesis, usando para ello
una pila para guardar los operadores. Luego que ya está todo en un
arreglo o vector, como quieras, entonces habría que aplicarle la
operación de evaluación de la expresión, que hay que usar otra pila,
pero esta vez para los operandos.

> alguna vez yo trabaje con pilas pero estaticas(es decir usando un
> vector simple en ves de una lista enlzada) ya que aun no trabajo con
> pilas dinamicas y no las domino aun(aun soy principiante en progrmacion).

Bueno, si el caso es un ejercicio sencillo, no me parece que el
problema sea una pila estática, porque no se me ocurre que alguien
ponga más de 1000 operandos o algo por el estilo, que sería sencillo
declararlo en una variable local. De otro modo, puedes utilizar la
clase stack de la librería stl.

> Entiendo la logica pero no tengo claro como hacer el codigo ya que
> me hago la idea que pasaria si la operacion tiene varios parentesis agrupados:
> xejemplo:
>  5+6*(4+(5+7)*(6-(5*4)))

Bueno, lo más difícil en esto es el algoritmo de solución, la
programación es basura siempre, por eso a mí me gusta más esta parte.
Por ejemplo, en tu nuevo ejemplo este serían los pasos de donde pienso
que puedar generalizar el algoritmo y sacar ya un código que puedas
compartir con todos nosotros :), anda y así lo veo por primera vez en
c/c++.

Para el análisis, voy a llevar tres elementos, el primero es la
descripción del paso, que ojalá no se me olvide alguno, el segundo es
el estado de la pila de los operadores que le llamaré PO, y el tercero
la expresión en notación postfija de cómo va quedando, que le
llamaremos NP.

Lo primero que hacemos es agregar un ( a la pila, a partir de ahora
push, y le agrego al final de la cadena de la expresión en notación
infija un ), quedando esta como: 5+6*(4+(5+7)*(6-(5*4)))), y ahora si
empezamos, promete ser largo esto. :)

1. tomo el número 5 y lo pongo en NP.
PO: (
NP: 5

2. tomo el operador aritmético +, y entonces analizo la cima de la
pila, si en ella hay otros operadores de menos prioridad o igual los
voy sacando y colocando en la expresión NP y al final lo coloco en la
pila, sino lo coloco en la pila.
PO: (,+
NP: 5

3. tomo el número 5 y lo pongo en NP.
PO: (,+
NP: 5,6

4. tomo el operador aritmético *, y entonces realizo la misma
operación que en 2.
PO: (,+,*
NP: 5,6

5. tomo el paréntesis ( y lo agrego a la pila.
PO: (,+,*,(
NP: 5,6

6. tomo el número 4 y lo pongo en NP.
PO: (,+,*,(
NP: 5,6,4

7. tomo el operador aritmético +, y entonces realizo la misma
operación que en 2.
PO: (,+,*,(,+
NP: 5,6,4

8. realizo la misma operación que en 5.
PO: (,+,*,(,+,(
NP: 5,6,4

9. tomo el número 5 y lo pongo en NP.
PO: (,+,*,(,+,(
NP: 5,6,4,5

10. tomo el operador aritmético +, y entonces realizo la misma
operación que en 2.
PO: (,+,*,(,+,(,+
NP: 5,6,4,5

11. tomo el número 7 y lo pongo en NP.
PO: (,+,*,(,+,(,+
NP: 5,6,4,5,7

12. tomo el paréntesis ), y analizo la pila, sacando operadores y
colocandolos en la cadena hasta que encuentre el paréntesis abierto, y
al final, quito el paréntesis abierto de la pila.
PO: (,+,*,(,+,
NP: 5,6,4,5,7,+

13. tomo el operador aritmético *, y entonces realizo la misma
operación que en 2.
PO: (,+,*,(,+,*
NP: 5,6,4,5,7,+

14. realizo la misma operación que en 5.
PO: (,+,*,(,+,*,(
NP: 5,6,4,5,7,+

15. tomo el número 6 y lo pongo en NP.
PO: (,+,*,(,+,*,(
NP: 5,6,4,5,7,+,6

16. tomo el operador aritmético -, y entonces realizo la misma
operación que en 2.
PO: (,+,*,(,+,*,(,-
NP: 5,6,4,5,7,+,6

17. realizo la misma operación que en 5.
PO: (,+,*,(,+,*,(,-,(
NP: 5,6,4,5,7,+,6

18. tomo el número 5 y lo pongo en NP.
PO: (,+,*,(,+,*,(,-,(
NP: 5,6,4,5,7,+,6,5

19. tomo el operador aritmético *, y entonces realizo la misma
operación que en 2.
PO: (,+,*,(,+,*,(,-,(,*
NP: 5,6,4,5,7,+,6,5

20. tomo el número 4 y lo pongo en NP.
PO: (,+,*,(,+,*,(,-,(,*
NP: 5,6,4,5,7,+,6,5,4

21. tomo el paréntesis ), y entonces realizo la misma operación que
en 12.
PO: (,+,*,(,+,*,(,-
NP: 5,6,4,5,7,+,6,5,4,*

22. tomo el paréntesis ), y entonces realizo la misma operación que
en 12.
PO: (,+,*,(,+,*,
NP: 5,6,4,5,7,+,6,5,4,*,-

23. tomo el paréntesis ), y entonces realizo la misma operación que
en 12.
PO: (,+,*,
NP: 5,6,4,5,7,+,6,5,4,*,-,*,+

24. tomo el paréntesis ) final, el que añadimos al principio, y entonces
realizo la misma operación que en 12.
PO:
NP: 5,6,4,5,7,+,6,5,4,*,-,*,+,*,+

Y hemos terminado. Sin embargo, en este ejemplo hay casos que no
se han visto, como por ejemplo en el paso 2, qué pasaría si:

...
PO: (,*
NP: 5,6

2. tomo el operador aritmético +, y entonces analizo la cima de la
pila, si en ella hay otros operadores de menos prioridad o igual los
voy sacando y colocando en la expresión NP y al final lo coloco en la
pila, sino lo coloco en la pila.
PO: (,+
NP: 5,6,*
...

> bueno espero respuesta amigo(s)

Ufff... esta me consumió tiempo, pero me resultó agradable. Cuando
resulvas esta parte hablamos de como evaluarla, esta sí es más fácil, y
pon ejemplos más cortos :)

> saludos.

-- 
Salu2,
 Gilbert





Más información sobre la lista de distribución Cconclase