You are on page 1of 8

ESCUELA POLITECNICA NACIONAL FACULTAD DE INGENIERIA EN SISTEMAS Estructura de datos Nombre: Alexander Pinchao Tema: Calculadora postfija Definicin.

Una expresin postja esta formada por una serie de operadores y operan dos, donde un operador va precedido por sus operadores 1 2 3 + donde el 2 y el 3 preceden al operador *, puesto que son sus operandos, y el 1 y el resultado de 2 3 preceden al operador +. Se evala de la siguiente forma: cuando se encuentra un operando, se apila en la pila; cuando se encuentra un operador, el nmero apropiado de operandos son desapilados de la pila, se evala la operacin indicada por el operador, y el resultado se apila de nuevo en la pila. Para operadores binarios, que son los ms comunes, se desapilan dos operandos. Ejemplos de operadores binarios son la suma (+), la resta (), la multiplicacin (*) y la divisin (/). Cuando la expresin postja ha sido procesada completamente, el nico elemento que quede en la pila ser el resultado de la evaluacin, es decir, el valor equivalente a evaluar la expresin postja. La notacin postja es una forma natural de evaluar expresiones, pues con ella no son necesarias reglas de precedencia ni existen ambigedades en la evaluacin.

El ejemplo de evaluacin de la expresin postja 1 2 3 +, correspondiente a la expresin inja 1 +2 3. Se muestra cmo se va realizando el anlisis de la expresin paso a paso. Para cada smbolo que se analiza se muestra la accin a realizar as como el estado de la pila. La evaluacin procede de la siguiente manera: el 1, el 2 y el 3 son apilados, en ese orden en la pila. Para procesar el *, se desapilan los dos elementos superiores de la pila: esto es, el 3 y despus el 2. Obsrvese que el primer elemento desapilado se convierte en el operando derecho del operador, y el segundo elemento desapilado en el operando izquierdo; por tanto, los parmetros se obtienen de la pila en orden inverso al natural. Para la multiplicacin, esto no importa, pero para la resta y la divisin, desde luego que si. El resultado de la multiplicacin es 6, que es apilado en la pila. En este momento, la cima de la pila es un 6, y debajo hay un 1. Para procesar el +, se desapilan el 6 y el 1, y su suma, 7, se apila. En este punto, la expresin se ha le ido completamente y la pila solo tiene un elemento. Por tanto, la respuesta nal a la evaluacin de la expresin es 7. Como hay 3 operandos y 2 operadores, habr 5 pasos y 5 apilamientos para evaluar la expresin. As pues, la evaluacin de una expresin postja requiere un tiempo lineal. Parmetros. Entrada.- Strings Salida.- Float y String Retorna.- NONE

Problema .Se pretende implementar una calculadora de nmeros enteros en notacin postja. Para ello, el usuario dispone de una pila donde almacenar los operandos y los resultados de las operaciones parciales, conforme estas se realizan. Adems, el usuario debe disponer de una serie de memorias de los resultados, donde podr almacenar, en cada momento, el contenido de la cabeza de la pila de operandos (una cola ). El nmero de memorias almacenadas puede ir variando a lo largo de la ejecucin de la calculadora. Se trata de que el usuario pueda introducir por teclado una serie de comandos que le permitan operar con la calculadora y las memorias. Cumpliendo con las siguientes condiciones Todos los ingresos de los usuarios debern realizarse en una cola Se debe designar un smbolo para terminar el ingreso de caracteres No se podr ingresar mas caracteres luego de ingresado el smbolo de cierre Todos los errores del usuario debern ser notificados con un mensaje Se deben revisar todos los escenarios posibles La calculadora usara notacin polaca inversa El programa constara de una cola y una pila Se podr ingresar nmeros reales Cuando se produzca un error el programa deber notificar cual fue el error

La calculadora realizara las operaciones bsicas (+,-,*,/)

Desarrollo de escenarios.10.- Si el carcter ingresado no es un carcter nmero saltar a 30 20.-ingresar el carcter numrico en la pila 30.- si el carcter ingresado es igual a *,-,+,/ ir a 50 40.- Mostrar mensaje carcter ingresado no valido debe de ser numrico 50.- si nmero de carcter numricos menos 1 no es igual a numero de caracteres ir a 70 60.- permitir el ingreso del carcter de cierre 70.- si nmero de caracteres numricos menos 1 no es menor al nmero de caracteres de operacin ir a 90 80.- ingresar el carcter de operacin 90.- mostrar el mensaje a usado mas operadores de los necesarios, se borrara los que estn de sobra 100.- si operacin no es igual a / ir a 130 110.- si operando2 no es igual a cero ir a 130 120.- mostrar mensaje indeterminado divisin por cero e ir a 150 130.- imprimir resultado 140.- imprimir secuencia postfija 150.- salir Codigo fuente.// sol.cpp: archivo de proyecto principal. #include "stdafx.h" #include <iostream> #include <queue> #include <stack> #include <string> #include <cmath> #include <stdio.h> #include <conio.h> #include <stdlib.h> using namespace std; using namespace System;

//Descripcion: Funcion para deplegar la cola en cosola void DesplegarCola(queue<char*> cola){ queue<char*> cola_aux; cola_aux=cola;//almacenamos para evitar perdida de datos en la funcion pop cout<<" "; while(!cola_aux.empty()) { cout << cola_aux.front()<<" "; cola_aux.pop(); } } //Funcion para desplegar una pila en consola void DesplegarPila(stack<float> pila){ cout<<" "; while(!pila.empty()) { cout << pila.top()<<endl; pila.pop(); } } //Descripcion: Funcion que Devuelve el valor true si la cadena resulta un numero bool EsNumero(char *cadena){ int i=0,l; l=strlen(cadena); int num=0; int contadorComas=0; while(i<l){ if(cadena[i]>='0'&&cadena[i]<='9'||cadena[i]==','){ num++; } if(cadena[i]==',')contadorComas++; i++; } //tiene que existir solo una coma decimal en la expresion: contador=1; //y todos los elemntos i de la cadena son numeros i=num if(num==i&&contadorComas<=1) return true; return false; } //Descripcion: Funcion que Devuelve el valor true si la cadena resulta un operador bool EsOperador(char *cadena){ int i=0,longitud; longitud=strlen(cadena); while(i<longitud){ if(cadena[i]=='+'||cadena[i]==''||cadena[i]=='*'||cadena[i]=='/')return true; i++; } return false; } //Descripcion: Funcion que devulve el numero total de numeros que existen en una cola. int ContadorNumeros(queue<char*> cola){ queue<char*> cola_aux; int contador=0; cola_aux=cola;//almacenamos la cola para evitar perdida de datos en la funcion pop

while(!cola_aux.empty()) { if(EsNumero(cola_aux.front())==true)contador++; cola_aux.pop(); } return contador; } //Descripcion:Funcion que devulve el numero total de operadores que existen en una cola. int ContadorOperadores(queue<char*> cola){ queue<char*> cola_aux; int contador=0; cola_aux=cola;//almacenamos la cola para evitar perdida de datos en la funcion pop while(!cola_aux.empty()) { if(EsOperador(cola_aux.front())==true)contador++; cola_aux.pop(); } return contador; } //Descripcion: Mediante esta funcion determianmos si una expresion //pertenece a la notacion polaca inversa bool ValidarExpresionPostfija(queue<char*> cola){ queue<char*> cola_aux; cola_aux=cola; int numeros=0; int operadores=0; while(!cola_aux.empty()) { /*La cantidad de numeros duarante todo el proceso siempre es mayor a la cantidad de operadores*/ if(EsNumero(cola_aux.front())==true)numeros++; if(EsOperador(cola_aux.front())==true)operadores++; if(operadores>=numeros)return false; cola_aux.pop(); } //al final la cantidad de numeros es mayor en 1 a la cantidad de operadores if(numeros!=(operadores+1))return false; return true; } //Descripcion: Si la cadena de caracteres tiene un coma esta funcion la devovlvera su posicion int PosicionComaDecimal(char *cadena){ int i=0,longitud; int pos=-1; longitud=strlen(cadena); while(i<longitud){ if(cadena[i]==','){ pos=i; return pos; } i++; } return pos;

} //Descripcon: La transformacion se realiza considerando una cadena que //contenga una coma o ninguna. float Transforma_Char_a_Float(char *cadena){ int i,j,longitud; float numeroAux,numero; numero=0; i=0; j=0; longitud=strlen(cadena); //Si en la cadena no exista la coma decimal if(PosicionComaDecimal(cadena)==-1){ while(i<longitud){ if(cadena[i]>='0'&&cadena[i]<='9'){ numeroAux=cadena[i] - (float)'0'; numero+=numeroAux*(int)pow(10.00,((longitud)-(i+1))); i++; } } return numero; } numero=0; i=0; j=0; //Si la coma decimal existe, por la coma decimal la longitude se disminuye en uno if(PosicionComaDecimal(cadena)>-1){ while(i<longitud){ if(cadena[i]>='0'&&cadena[i]<='9'){ numeroAux=cadena[i] - (float)'0'; numero+=numeroAux*(float)pow(10.00,((longitud-1)-(j+1))); j++; } i++; } //se obtiene el numero sin coma, y se lo divide de acuerdo a la posicion de la coma para corregir numero=numero/(float)(pow(10,((longitud-1)(float)PosicionComaDecimal(cadena)))); return numero; } return 0; }; //Programa principal int main(int argc, char *argv[]) { queue <char*> cola; stack<float> pila; char *cadena=new char[10]; string texto=""; float num2,num1; char *opcion=new char[10]; int opcion2; float opcion3; bool DivCero=false;

cout<<" do{ do{ regresar al menu:\n

CALCULADORA POSTFIJA "<<endl;

cout<<"\n 1.-INGRESO EXPRESION POSTFIJA.\n 0.-SALIR.\n\tr.Opcion: "; cin>>opcion;

} while(EsNumero(opcion)==false); opcion3=Transforma_Char_a_Float(opcion); if(opcion3==1){ do{ if(!pila.empty())pila.pop();//borramos un elemnto para evitar acumulacion cout<<"*Ingreso:\n"; do{ cout<<" "; cin>>texto; cadena=strdup(texto.c_str()); if(cadena[0]=='r'){ break; } cola.push(cadena); } while(cadena[0]!='='); if(cadena[0]=='r'){ break; }

if(ValidarExpresionPostfija(cola)==false)cout<<"\nExpresion no valida\n"; } while(ValidarExpresionPostfija(cola)==false); cout<<endl; if(cadena[0]!='r'||ValidarExpresionPostfija(cola)==true){ DesplegarCola(cola); while(!cola.empty()) { //la pila almacenara solo numeros if(EsNumero(cola.front())==true) { pila.push(Transforma_Char_a_Float(cola.front())); } //Operaciones aritmeticas //De acuerdo a cada operador los elemntos de la pila se iran modificando if(EsOperador(cola.front())==true) { if(cola.front()[0]=='+'){ num2=pila.top(); pila.pop(); num1=pila.top(); pila.pop(); pila.push(num1+num2); } if(cola.front()[0]=='-'){ num2=pila.top();

pila.pop(); num1=pila.top(); pila.pop(); pila.push(num1-num2); } if(cola.front()[0]=='*'){ num2=pila.top(); pila.pop(); num1=pila.top(); pila.pop(); pila.push(num1*num2); } if(cola.front()[0]=='/'){ num2=pila.top(); //verificamos si en la expresion existe la division por cero if(num2!=0){ pila.pop(); num1=pila.top(); pila.pop(); pila.push(num1/num2); } else DivCero=true; } } cola.pop(); } //Aviso sobre el resultado inesperado if(DivCero==true) cout<<"INF: Division por cero no determinada"<<endl; else { cout<<" "; DesplegarPila(pila); } } } if(opcion3==0){ printf("\n Para salir presione cualquier otra tecla . . ."); if((opcion2 = getch()) ==114)opcion[0]='5'; cout<<endl; } } while(opcion!=0); return 0; }

You might also like