![]() |
| 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/

No hay comentarios:
Publicar un comentario