Documente Academic
Documente Profesional
Documente Cultură
Expresión postfija Se denomina expresión postfija a aquella que contiene los operandos
se encuentran antes de los operadores, respetando la jerarquía de los mismos, no se
consideran los paréntesis, ya que la expresión postfija respeta la jerarquía de operadores
por sí misma. Ejemplo: AB+C*.
• Planteamiento del
problema
La problemática con la que nos encontramos esta vez fue la de cómo poder agilizar el
proceso de conversión de expresiones aritméticas en su notación infija a su notación
posfija.
1
• Diseño y funcionamiento de la solución
2
*Descripción del funcionamiento de los algoritmos que se apoyan del TAD
pila.
-Validación de paréntesis: El propósito de este algoritmo es verificar que todos los
pares “( )” aparezcan congruentemente dentro de la expresión infija, por ejemplo,
(A+B)/(C+D) tiene correctos estos caracteres, sin embargo, (A+B))/(C+D( es incorrecto.
Primeramente, se recorre la expresión y se analiza cada paso por los índices, si el caracter
encontrado es ‘(’, este se mete a la pila. Si el caracter es ‘)’, se saca uno de los caracteres
(que forzosamente es un paréntesis cerrado).
Si al finalizar el recorrido de la cadena, la pila queda con algún elemento dentro, los
paréntesis están mal escritos, hay un lugar donde no cierra un paréntesis.
Si al finalizar el recorrido de la cadena, la pila queda queda vacía, pero la expresión aún
tiene caracteres ‘)’, los paréntesis están mal escritos, hay un lugar donde no abre un
paréntesis.
Si el caracter es ‘)’, se va a sacar todo de la pila, hasta donde exista un ‘(’ empilado, y se
colocarán los caracteres en la expresión posrfija, en el orden que fueron saliendo.
3
El proceso debe devolver una cadena con la expresión convertida a
postfijo.
Para realizar este procedimiento, es necesario haber pasado antes por la validación.
Creamos un arreglo auxiliar que guardará todas las letras que se encuentren en
nuestra expresión postfija, después de que guardamos todas las letras de la
expresión para mandarla a otra función que nos quitará todas la letras repetidas.
Teniendo el arreglo de todas las letras sin repetirlas haremos otro arreglo que
guardará los valores de cada letra para usar esos dos arreglos como referencia para
recorrer la expresión postfija e ir evaluando con los valores que se le asignó a cada
letra.
• Implementación de la solución
Paso 1 (Evaluar paréntesis). Lo primero que se debe realizar es que nuestra expresión sea
válida, revisando que todos los paréntesis tengan su par y no falte uno para abrir o para
cerrar.
Paso 2 (Convertir a postfija). Una vez validados los paréntesis de la expresión podremos
proceder a la conversión de la expresión de infija a postfija. Lo primero que tenemos que
tener en cuenta es la precedencia de la operación que se va obteniendo de la expresión.
Ocuparemos una pila para ir guardando los operadores.
Las reglas para insertar los operadores a la pila son las siguientes:
4
1. Si se tiene en el tope de la pila un operador de igual precedencia que el que se
tiene en la cadena, los operadores se cambian. 2. Si el operador es de mayor procedencia que
el que se tiene en el tope de la pila, se
agrega a la pila. 3. Si el operador es de menor precedencia que el que se tiene en el tope de la
pila, sacas todos los operadores hasta llegar a un paréntesis abierto, se saca el
paréntesis abierto e insertas el operador de la cadena. 4. Si te encuentras un paréntesis
abierto se inserta a la pila. 5. Si te encuentras un paréntesis cerrado sacas los
operadores hasta llegar al
paréntesis
abierto.
5
• Funcionamiento
6
FIGURA 2 y 3. Pantalla de salida al evaluar una expresión posfija.
7
• Posibles mejoras
• Conclusiones
Las estructuras de datos son una herramienta sumamente útil al trabajar con proyectos
donde la información es demasiada, y es posible con ellas, optimizar tiempos de
operación de los procesos.
Gracias a esta práctica conseguimos ejercitar mucho el concepto del TAD Pila ya que
como cualquier otra estructura de datos, se puede aplicar en muchos problemas y tareas
en la computación porque por su particular forma de manipular la información podrás
notar en qué tipo de problemas se debe atacar usando una Pila.
• Anexo
- TADPilaEst.h
/*
AUTORES:
8
Tellez Perez Juan Manuel
Febrero 2019
VERSIÓN: 1.0
*/
//DEFINICIONES DE CONSTANTES
9
#define MAX_ELEMENT 1000
#define TRUE 1
#define FALSE 0
char c;
float valor;
//***
10
//***
//***
}elemento;
//Definir una pila (Se modela con una estructura que unicamente
incluye un puntero a "elemento")
int tope;
//El tope es un entero (Indice del arreglo de elementos)
}pila;
11
void Initialize(pila *s);
12
//Elimina pila (Borra a todos los elementos y a la pila de
memoria)
- TADPilaEst.c
/*
AUTORES:
Febrero 2019
VERSIÓN: 1.0
13
DESCRIPCIÓN: TAD pila o stack.
*/
//LIBRERAS
#include<stdio.h>
#include<stdlib.h>
#include "TADPilaEst.h"
14
//DEFINICIÓN DE FUNCIONES
/*
Devuelve:
*/
(*s).tope=-1; //s->tope=-1;
return;
15
/*
Devuelve:
y se causará en error.
*/
s->tope++;
16
if(s->tope==MAX_ELEMENT)
printf("\nERROR: PUSH(*S, E)
DESBORDAMIENTO, NO MÃS ESPACIO EN LA PILA");
exit(1);
s->arreglo[s->tope]=e;
return;
/*
17
Observaciones: El usuario a creado una pila y s tiene la
referencia a ella, s ya ha sido inicializada.
*/
elemento r;
if(s->tope==-1)
printf("\nERROR POP(*S):
SUBDESBORDAMIENTO, NO HAY ELEMENTOS EN LA
PILA");
exit(1);
18
r=s->arreglo[s->tope];
s->tope--;
return r;
/*
*/
boolean r;
if(s->tope==-1)
19
{
r= TRUE;
else
r= FALSE;
return r;
/*
20
Ademas no se valida si la pila esta vacia antes de consultar al
elemento del tope (causa error si esta esta vacÃa).
*/
if(s->tope==-1)
printf("\nERROR TOP(*S):
SUBDESBORDAMIENTO, NO HAY ELEMENTOS EN LA
PILA");
exit(1);
return s->arreglo[s->tope];
21
/*
*/
return s->tope+1;
/*
Devuelve:
*/
//s->tope=-1;
Initialize(s);
return;
- TADPilaDin.h
/*
AUTORES:
23
Ayona Lopez Eugenio Milton
Febrero 2019
VERSIÓN: 1.0
*/
24
//DEFINICIONES DE CONSTANTES
#define TRUE 1
#define FALSE 0
char c;
}elemento;
25
de la pila (Nodo), lo que incluira a un elemento y a un apuntador
al siguiente nodo
elemento e;
}nodo;
//Definir una pila (Se modela con una estructura que unicamente
incluye un puntero a "elemento")
nodo *tope;
}pila;
//DECLARACIÓN DE FUNCIONES
26
void Initialize(pila *s); //Inicializar pila
(Iniciar una pila para su uso)
- TADPilaDin.c
/*
AUTORES:
27
Ayona Lopez Eugenio Milton
Febrero 2019
VERSIÓN: 1.0
28
COMPILACIÓN PARA GENERAR EL CÓDIGO OBJETO:
gcc TADPilaEst.c -c
*/
//LIBRERAS
#include <stdio.h>
#include <stdlib.h>
#include "TADPilaDin.h"
//DEFINICIÓN DE FUNCIONES
/*
Devuelve:
29
si esto no ha pasado se ocasionara un error.
*/
s->tope=NULL; //(*s).tope=NULL;
return;
/*
Devuelve:
30
y no se acaba la memoria
*/
nodo *aux;
aux=malloc(sizeof(nodo));
if(aux==NULL)
printf("\nERROR-Push(&s,e): Desbordamiento de
la pila, no hay más memoria disponible");
exit(1);
(*aux).e=e; //aux->e=e;
31
aux->abajo=s->tope;
s->tope=aux;
return;
/*
*/
32
elemento Pop (pila *s)
elemento r;
nodo *aux;
if(s->tope==NULL)
printf("\nERROR-e=Pop(&s): Subdesbordamiento
de la pila, no hay elementos en la pila");
exit(1);
r=s->tope->e;
aux=s->tope;
s->tope=s->tope->abajo;
free(aux);
33
return r;
/*
*/
boolean r;
if(s->tope==NULL)
r=TRUE;
34
}
else
r=FALSE;
return r;
/*
35
*/
if(s->tope==NULL)
printf("\nERROR-e=Top(&s):
Subdesbordamiento de la pila, no hay elementos en la pila");
exit(1);
return s->tope->e;
/*
36
Recibe: int *s (Referencia a la pila "s" a operar)
*/
nodo *aux;
int tam_pila=0;
aux=s->tope;
if(aux!=NULL)
tam_pila++;
while(aux->abajo!=NULL)
tam_pila++;
aux=aux->abajo;
37
}
return tam_pila;
/*
Devuelve:
*/
nodo *aux;
if(s->tope!=NULL)
38
{
while(s->tope!=NULL)
aux=s->tope->abajo;
free(s->tope);
s->tope=aux;
return;
- Biblioteca.h
/*
//NUEVO PUSH
39
AUTORES:
Febrero 2019
VERSIÓN: 1.0
Lista de funciones:
40
que se importa en el archivo principal.
*/
#include "TADPilaEst.h"
#define TAM_CADENA_LITERALES 55
#define LIM_INFERIOR 65
#define LIM_SUPERIOR 90
void Menu();
/*
Validacion de parentesis:
41
*/
/*
*/
/*
Recibe...
42
-la direccion de la cadena donde se escribira la conversion de
infija a posfija.
Devuelve...
-Nada.
*/
/*
la evaluación.
*/
/*
43
y regresarlo a la pila posteriorente en Evaluar_Expresion.
*/
void Obtener_Valores();
/*
*/
44
- Biblioteca.c
/*
//NUEVO PUSH
AUTORES:
Febrero 2019
VERSIÓN: 1.0
Lista de funciones:
45
Cada una de las funciones que aquí se declaran, cumplen un
objetivo
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include<math.h>
#include "Biblioteca.h"
46
void Menu()
printf("\n1.Corregir expresion");
printf("\n2.Validar Parentesis.");
printf("\n3.Pasar a Posfija.");
printf("\n4.Evaluar expresion");
printf("\n5.Salir\n");
return;
/*
47
Efecto: La cadena que ingresamos puede o no estar correcta,
comprueba eso y
*/
boolean validado;
Initialize(&pila_parentesis);
tamCadena= strlen(cad);
48
for(i=0; i<=tamCadena; i++) //recorre la cadena
if(cad[i]=='(')//Ingresa en la Pila si es (
elm.c='(';
Push(&pila_parentesis, elm);
else
goto regresar; //puesto para poder salir del if, y tome el valor
TRUE al seguri a la condicion final
49
}
else
Pop(&pila_parentesis);
if(Empty(&pila_parentesis))
validado=TRUE;
else
validado=FALSE;
50
AQUI ERA EL ERROR, donde??
return validado;
*/
51
int i;
//Vaciar_Arreglos(&cad[0], &cad_posfija[0],
&literalesDeExpresion[0], &valoresDeLiterales,
&auxiliarAntiRepeticion[0]);
scanf("%s", cad);
for(i=0;i<strlen(cad);++i){
Corregir_Expresion(cad);
52
//printf("%s\n", cad);
return;
/*
principio
*/
53
pila pila_posfija; // Guarda cadena
elemento aux_e; //
int i=0;
int aux=-1;
Initialize(&pila_posfija);
printf("\n");
if(!v) {
else
e.c = cad[i];
54
switch(e.c){ //Caracter actual
/*
*/
case '-':
case '+':
Push(&pila_posfija,e);
*/
55
++aux;
cad_posfija[aux] = Pop(&pila_posfija).c;
Push(&pila_posfija,e);
*/
{
56
++aux;
cad_posfija[aux] = aux_e.c;
} else
break;
se coloca
el caracter actual de la cadena en la pila*/
Push(&pila_posfija,e);
break;
57
/*
*/
case '*':
case '/':
if(Empty(&pila_posfija))
Push(&pila_posfija,e);
++aux;
cad_posfija[aux] = Pop(&pila_posfija).c;
Push(&pila_posfija,e);
58
else if(Top(&pila_posfija).c == '+' || Top(&pila_posfija).c
== '-') //caso precedencia mayor al caracter actual
Push(&pila_posfija,e);
while(!Empty(&pila_posfija))
aux_e = Pop(&pila_posfija);
if(aux_e.c != '('){
++aux;
cad_posfija[aux] = aux_e.c;
}else
break;
Push(&pila_posfija,e);
59
}
Push(&pila_posfija,e);
break;
case '^':
Push(&pila_posfija,e);
break;
while(Empty(&pila_posfija)==FALSE) //Mientras la
pila no este vacia saca elemetos de la pila NO ES TRUE !NO
FUNCIONA
60
tope
++aux;
cad_posfija[aux] = aux_e.c;
}else
break;
break;
Push(&pila_posfija,e);
break;
++aux;
61
cad_posfija[aux] = e.c;
break;
i++;
while(!Empty(&pila_posfija))
aux_e = Pop(&pila_posfija);
if(aux_e.c != '('){
++aux;
cad_posfija[aux] = aux_e.c;
62
}
Destroy(&pila_posfija);
return TRUE;
int o_aux=0; //
int j,k,l,m;
/*
63
Los siguientes 3 arreglos guardan las letras, sus valores, y sus
no repeticiones respectivamente,
*/
char literalesDeExpresion[90]="";
{
64
literalesDeExpresion[i_aux]=cad[j];
++i_aux;
No_Repite(literalesDeExpresion,i_aux,auxiliarAntiRepeticion);
scanf("%f", &valoresDeLiterales[auxiliarAntiRepeticion[k]]);
printf("\n");
65
//estos for solo prueban que los valores sean congruentes
printf("\n");
printf("\n\n");
return;
66
//funcion que evita la repeticion
int j=0,k=0,inicio,i;
for(i=0;i<tam;++i){
if(i==0){
resultado[j]=cadena[i];
}else{
for(inicio=0;inicio<=j;++inicio){
if((cadena[i]!=resultado[inicio])){
++k;
67
}else {
k=0;
break;
if(k==j+1){
++j;
resultado[j]=cadena[i];
k=0;
68
void Evaluar_Expresion(char* cad_posfija, float*
valoresDeLiterales)
pila resultado;
elemento numero_conv;
elemento valorNP;
char float_cad[2]="";
char cadena_num[strlen(cad_posfija)+10];
int control_cn=0;
int i;
float n1;
float n2;
Initialize(&resultado);
printf("Pasos:\n");
for(i=0;i<strlen(cad_posfija);i++)
69
switch(cad_posfija[i]){
case '+':
n1= Pop(&resultado).valor;
n2= Pop(&resultado).valor;
printf("%.2f + %.2f\n",n2,n1);
valorNP.valor= n1+n2;
Push(&resultado,valorNP);
break;
case '-':
n1= Pop(&resultado).valor;
n2= Pop(&resultado).valor;
printf("%.2f - %.2f\n",n2,n1);
valorNP.valor= n2-n1;
Push(&resultado,valorNP);
70
break;
case '/':
n1= Pop(&resultado).valor;
n2= Pop(&resultado).valor;
printf("%.2f / %.2f\n",n2,n1);
valorNP.valor= n2/n1;
Push(&resultado,valorNP);
break;
case '*':
n1= Pop(&resultado).valor;
n2= Pop(&resultado).valor;
printf("%.2f * %.2f\n",n2,n1);
valorNP.valor= n1*n2;
71
Push(&resultado,valorNP);
break;
case '^':
n1= Pop(&resultado).valor;
n2= Pop(&resultado).valor;
printf("%.2f ^ %.2f\n",n2,n1);
valorNP.valor= pow(n2,n1);
Push(&resultado,valorNP);
break;
default:
numero_conv.valor=valoresDeLiterales[cad_posfija[i]];
Push(&resultado,numero_conv);
break;
72
}
printf("\nResultado de la expresion
%.2f\n",Top(&resultado).valor);
- main.c
/*
*/
//EUGENIO CAMBIOS
#include <stdio.h>
#include "Biblioteca.h"
#include <stdlib.h>
#include <math.h>
73
//main
int main()
int j;
boolean v=FALSE,posv=FALSE;
float valoresDeLiterales[90];
char auxiliarAntiRepeticion[90]="";
Corregir_Expresion(cad);
Menu();
do
74
printf("\nExpresion: %s",cad);
printf("\nSelecciona opcion\n");
scanf("%d", &opc);
switch(opc)
case 1:
system("cls");
Menu();
Corregir_Expresion(cad);
break;
case 2:
v = Validar_Parentesis(cad);
if(v){
system("cls");
Menu();
75
printf("\nParentesis validos, continua...\n");
else
system("cls");
Menu();
Corregir_Expresion(cad);
break;
case 3:
//system("cls");
Menu();
for(j=0;j<TAM;++j)//ESTO CAUSABA
76
EL ERROR DE LIMPIEZA DE LA CADENA POSTFIJA
cad_posfija[j]=0;
break;
case 4:
if(v){
if(posv){
for(j=0;j<90;++j)//ESTO
CAUSABA EL ERROR DE LIMPIEZA DE REPETICION DE
ELEMENTOS
auxiliarAntiRepeticion[j]=0;
Obtener_Valores(cad,valoresDeLiterales,auxiliarAntiRepeticion)
;
Evaluar_Expresion(cad_posfija,valoresDeLiterales);
77
}
else
}else{
system("cls");
Menu();
break;
}else
} while (opc<5);
return 0;
78
}
79