El algoritmo permite calcular el resultado de una expresión aritmética ingresada por teclado |
#include <iostream> #include <string> #include <sstream> #include <tgmath.h> using namespace std; //PRIMERA PARTE: PILA DE OPERANDOS int xSize; int xCab; bool xFull; bool xHas; struct structXHeap { double dat; } *xHeap; void xInit(int size) { xSize = size; xCab = -1; xFull = false; xHas = false; xHeap = new structXHeap[xSize]; } bool xPush(double xdat) { if(xFull) return false; else { xCab++; xHeap[xCab].dat = xdat; xHas = true; if(xCab == xSize-1) xFull = true; return true; } } double xTop() { if(xHas) return xHeap[xCab].dat; else return -1; } double xPop() { if(xHas) { double dat_out = xTop(); xCab--; xFull = false; if(xCab<0) xHas = false; return dat_out; } else return -1; } int xLength() { return xCab+1; } double *getXHeap() { double *xHeapGeted = new double[xCab+1]; int j=xCab; for(int i=0;i<=xCab;i++) { xHeapGeted[j] = xHeap[i].dat; j--; } return xHeapGeted; } //SEGUNDA PARTE: PILA DE OPERADORES int ySize; int yCab; bool yFull; bool yHas; struct structYHeap { char dato; int prioridad; } *yHeap; void yInit(int size) { ySize = size; yCab = -1; yFull = false; yHas = false; yHeap = new structYHeap[ySize]; } bool yPush(char yDat) { if(yFull) return false; else { yCab++; yHeap[yCab].dato = yDat; yHas = true; if(yCab == ySize-1) yFull = true; return true; } } char yTop() { if(yHas) return yHeap[yCab].dato; else return '\0'; } char yPop() { if(yHas) { char dato_out = yTop(); yCab--; yFull = false; if(yCab<0) yHas = false; return dato_out; } else return '\0'; } int yLength() { return yCab+1; } char *getYHeap() { char *yHeapGeted = new char[yCab+1]; int j=yCab; for(int i=0;i<=yCab;i++) { yHeapGeted[j] = yHeap[i].dato; j--; } return yHeapGeted; } //TERCERA PARTE: LÓGICA DE USOS int calculatePriority(char xOperator) { switch (xOperator)//Tabla de prioridades de los operadores { case '(': return 0; case ')': return 0; case '+': return 1; case '-': return 1; case '/': return 2; case '*': return 2; case '^': return 3; default: return 0; } } bool analyzeInfix(string infix) { int open=0; int closer=0; for(unsigned int i=0; i<infix.size() ;i++) { if(infix[i]=='(') open++; if(infix[i]==')') closer++; } if(open==closer) return true; else return false; } string convertToPostfix(string infix) { string postfix=""; yInit(100); for(unsigned int i=0;i<infix.size();i++) { char xdato=infix[i]; int ascii=int(xdato);//Extrae el código ASCII de un caracter if(ascii>47 && ascii<58)//Si el codigo ASCII esta entre estos valores, entonces es un número natural postfix+=xdato; else//Si no es un número natural entre en este "else" { if(xdato=='(')//Si es un paréntesis izquierdo simplemente se colocará en la pila yPush(xdato);//Se agrega a la pila de operadores else { if(xdato==')')//Si es un paréntesis derecho debe sacar todos los operadores almacenados hasta que se encuentre un paréntesis izquierdo { while(yTop()!='(')//Extrae los operadores hasta que se encuentre un paréntesis izquierdo postfix+=yPop(); yPop();//Este último paréntesis izquierdo no fue eliminado de la pila, pero acá se elimina } else//Si no es paréntesis entonces es un operador { if(!yHas)//Verifica si la pila de operadores está vacía yPush(xdato);//De ser así solo colocamos el operador en la pila else { if(calculatePriority(xdato)<=calculatePriority(yTop()))//Compara la prioridad del operador entrante con el que está en la cabecera de la pila { char operador=yPop();//Si es menor debemos sacar el que está en la cabecera yPush(xdato);//Y colocar el entrante en la cabecera postfix+=operador;//y el que salio lo colocamos en postfix } else yPush(xdato);//Si el operador entrante fuese de mayor prioridad que el de la cabecera, simplemente se coloca en la pila } } } } } while(yHas) postfix+=yPop(); return postfix; } string invertExpression(string infix) { string infixInvertida=""; for(unsigned int i=0;i<infix.size();i++) { char caracter = infix[i]; if(caracter==')') caracter = '('; else { if(caracter=='(') caracter = ')'; } infixInvertida=caracter+infixInvertida; } return infixInvertida; } double postfixResult(string postfix) { xInit(100); for(unsigned int i=0;i<postfix.size();i++) { char xdato=postfix[i]; int ascii=int(xdato);//Extrae el código ASCII de un caracter if(ascii>47 && ascii<58)//Si el codigo ASCII esta entre estos valores, entonces es un número natural xPush(xdato-'0'); else { double num1=xPop(); double num2=xPop(); switch(xdato)//Tabla de operaciones { case '+': xPush(num2+num1);break; case '-': xPush(num2-num1);break; case '/': xPush(num2/num1);break; case '*': xPush(num2*num1);break; case '^': xPush(pow(num2,num1));break; } } } return xPop(); } //MAIN int main() { string infix; cout << "Ingrese una expresión aritmética: "; cin >> infix; if(analyzeInfix(infix)) { string postfix = convertToPostfix(infix); cout << to_string(postfixResult(postfix)); } else { cout << "Falta cerrar o abrir algunos paréntesis ()"; } }
Copiar, pegar y ejecutar este script en http://cpp.sh/