Mostrando entradas con la etiqueta C. Mostrar todas las entradas
Mostrando entradas con la etiqueta C. Mostrar todas las entradas

miércoles, 21 de septiembre de 2011

Cálculo de una expresión aritmética

calculo-de-una-expresion-aritmética
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/