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/

Frase palíndroma





PilaChar.h

#pragma once

class PilaChar
{
private:
int size;
int cab;//Cabecera de la pila
public:
bool llena;
bool hasElements;


struct structPila
{
wchar_t dato;
} *pila;

public:
PilaChar(int tam); //Constructor
bool push(wchar_t xdato);
wchar_t pop ();
wchar_t top ();
int length();
wchar_t *getPila();
};



PilaChar.cpp

#include "StdAfx.h"
#include "PilaChar.h"

PilaChar::PilaChar(int tam)
{
size = tam;
cab = -1; //Cabecera apunta a -1, entonces no hay elementos en la pila
pila = new structPila[size];

llena = false;
hasElements = false;
}

//Inserta un elemento en la pila
bool PilaChar::push(wchar_t xdato)
{
if(llena)
return false;
else
{
cab++;
pila[cab].dato = xdato;

hasElements = true;

if(cab == size-1)
llena = true;
}
}

//Extrae el elemento de la cabecera de la pila
wchar_t PilaChar::pop()
{
if(hasElements)
{
wchar_t dato_out = top();
cab--;

llena = false;

if(cab<0)
hasElements = false;

return dato_out;
}
else
return '\0';
}

//Muestra el elemento de la cabecera de la pila
wchar_t PilaChar::top()
{
if(hasElements)
return pila[cab].dato;
else
return '\0';
}

int PilaChar::length()
{
return cab+1;
}

wchar_t *PilaChar::getPila()
{
wchar_t *pilaGeted = new wchar_t[cab+1];

int j=cab;

for(int i=0;i<=cab;i++)
{
pilaGeted[j] = pila[i].dato;
j--;
}

return pilaGeted;
}


Descargar la solución completa de Pilas

Ruta de ida y vuelta





PilaString.h

#pragma once

class PilaString
{
private:
int size;
int cab;//Cabecera de la pila
public:
bool llena;
bool hasElements;

struct structPila
{
wchar_t *dato;
int tam;//Tamaño de cada elemento
} *pila;

public:
PilaString(int); //Constructor
bool push(System::String^ dato);
System::String^ pop ();
System::String^ top ();
int length();
System::String^ getPila ();
};




PilaString.cpp


#include "StdAfx.h"
#include "PilaString.h"

PilaString::PilaString(int tam)
{
size = tam;
cab = -1; //Cabecera apunta a -1, entonces no hay elementos en la pila
pila = new structPila[size];

llena = false;
hasElements = false;
}

//Inserta un elemento en la pila
bool PilaString::push(System::String^ dato)
{
if(llena)
return false;
else
{
cab++;
pila[cab].tam = dato->Length;
pila[cab].dato = new wchar_t[pila[cab].tam];

//Convertimos el string en un arreglo de caracteres!
for(int i=0;i<pila[cab].tam;i++)
pila[cab].dato[i] = dato[i];

hasElements = true;

if(cab == size-1)
llena = true;

return true;
}
}

//Extrae el elemento de la cabecera de la pila
System::String^ PilaString::pop()
{
if(hasElements)
{
System::String^ cadena = top();
cab--;

llena = false;

if(cab<0)
hasElements = false;

return cadena;
}
else
return "La pila está vacía";

}

//Muestra el elemento de la cabecera de la pila
System::String^ PilaString::top()
{
if(hasElements)
{
System::String^ cadena;

//Convertimos el arreglo de caracteres en un string !
for(int i=0;i<pila[cab].tam ;i++)
cadena += pila[cab].dato[i];

return cadena;
}
else
return "La pila está vacía";

}

int PilaString::length()
{
return cab+1;
}

System::String^ PilaString::getPila()
{
System::String^ pilaGeted = "";

for(int i=cab;i>=0;i--)
{
for(int j=0;j<pila[i].tam ;j++)
pilaGeted += pila[i].dato[j];

pilaGeted+="\r\n";//Salto de línea;
}

return pilaGeted;
}


Descargar la solución completa de Pilas

Listas simples






ListaChar.h

#pragma once

class ListaChar
{
private:
int cab;
int lib;
public:
int capacidad;

struct structLista
{
wchar_t dato;
int ptr;
}*lista;

public:
ListaChar(int);
bool agregar(wchar_t);
int buscar(wchar_t,int);
bool eliminar(wchar_t);
bool editar(wchar_t,wchar_t);
int length();
wchar_t *getLista();
};


ListaChar.cpp


#include "StdAfx.h"
#include "ListaChar.h"

ListaChar::ListaChar(int size)
{
lista = new structLista[size];
capacidad=size;

cab=999;
lib=0;
for(int k=0;k<size;k++)
{
lista[k].dato=' ';
lista[k].ptr=k+1;
}
lista[size-1].ptr=999;
}

bool ListaChar::agregar(wchar_t xdato)
{
if(length()!=capacidad)
{
lista[lib].dato=xdato;
if(cab==999)
{
cab=lib;
lib=lista[lib].ptr;
lista[cab].ptr=999;
}
else
{
int xptr=cab;

while(lista[xptr].ptr!=999)
xptr=lista[xptr].ptr;

int xlib=lib;
lista[xptr].ptr=lib;
lib=lista[xlib].ptr;
lista[xlib].ptr=999;
}
return true;
}
else
return false;
}

int ListaChar::buscar(wchar_t xdato,int xtipo)
{
int xptr=cab;
int xant=xptr;
int xExiste=0;

while(xptr!=999 && !xExiste)
{
if(lista[xptr].dato==xdato)
xExiste=1;
else
{
xant=xptr;
xptr=lista[xptr].ptr;
}
}

if(xExiste)
{
if(xtipo==0)
return xant;
else
return xptr;
}
else
return 999;
}

bool ListaChar::eliminar(wchar_t xdato)
{
int xptr=buscar(xdato,1);

if(length()>0)
{
if(xptr!=999)
{
int xant=buscar(xdato,0);
if(xant==xptr)
{
cab=lista[cab].ptr;
lista[xptr].ptr=lib;
lib=xptr;
}
else
{
lista[xant].ptr=lista[xptr].ptr;
lista[xptr].ptr=lib;
lib=xptr;
}

return true;
}
else
return false;
}
else
return false;
}

bool ListaChar::editar(wchar_t xdato,wchar_t ndato)
{
int xptr=buscar(xdato,1);

if(xptr!=999)
{
lista[xptr].dato=ndato;
return true;
}
else
return false;
}

int ListaChar::length()
{
int index=0;

int xptr=cab;

while(xptr!=999)
{
index++;
xptr=lista[xptr].ptr;
}

return index;

}

wchar_t *ListaChar::getLista()
{
wchar_t *listado = new wchar_t[length()];

int index=0;

int xptr=cab;

while(xptr!=999)
{
listado[index]=lista[xptr].dato;
index++;

xptr=lista[xptr].ptr;
}

return listado;
}

Descargar la solución completa de Listas