domingo, 27 de septiembre de 2009

Evaluador de expresiones matemáticas en C++

He aquí un programa que permite convertir una expresión infija a postfija y luego evaluarla para retornar un resultado (double). El programa hace uso de la STL de C++ estándar (por ejemplo en el uso de la pila).

Este código debe ser compilado con preferencia con G++; en Windows puede compilarlo con Dev-C++ (que trae el compilador MinGW)

También puede ser incluido en otros RAD que soporten C++ estándar (como Borland C++ Builder).

/*
Codigo creado por Christian Gómez Serapio
Facultad Nacional de Ingeniería. Oruro - Bolivia
www.estructurasydatos.blogspot.com
*/
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <stack>
#include <string>
using namespace std;
int prioridad(char op) {
 switch (op) {
  case '^': return 3;
  case '*':
  case '/': return 2;
  case '+': 
  case '-': return 1;
  case ')': return -1;
  default: return 0;
 }
} 
string convertir(string in) {
 stack<char> pila;
 string posf = "";
 for (int i=0; i < in.size(); i++) {
  switch (in[i]) {
   case '(':
    pila.push('(');
    break;
   case ')':
    while (!pila.empty() && pila.top() != '(') {
     posf += string(1,pila.top()) + " ";
     pila.pop();
    }
    pila.pop();
    break;
   case '+':
   case '-':
   case '*':
   case '/':
   case '^':
    while (!pila.empty() && prioridad(in[i]) <= prioridad(pila.top())) {
     posf += string(1,pila.top()) + " ";
     pila.pop();
    }
    pila.push(in[i]);
    break;
   default:
    while (isdigit(in[i]) || in[i] == '.') 
     posf += string(1, in[i++]);
    posf += " ";
    i--;
  }
 }
 while (!pila.empty()) {
  posf += string(1, pila.top()) + " ";
  pila.pop();
 }
 return posf;
}
double evaluar(string p) {
 stack<double> pila;
 double op1, op2;
 for (int i=0; i < p.size(); i+=2) {
  switch (p[i]) {
   case '^':
    op2 = pila.top(); pila.pop();
    op1 = pila.top(); pila.pop();
    pila.push(pow(op1, op2));
    break;
   case '*':
    op2 = pila.top(); pila.pop();
    op1 = pila.top(); pila.pop();
    pila.push(op1*op2);
    break;
   case '/':
    op2 = pila.top(); pila.pop();
    op1 = pila.top(); pila.pop();
    pila.push(op1 / op2);
    break;
   case '+':
    op2 = pila.top(); pila.pop();
    op1 = pila.top(); pila.pop();
    pila.push(op1 + op2);
    break;
   case '-':
    op2 = pila.top(); pila.pop();
    op1 = pila.top(); pila.pop();
    pila.push(op1 - op2);
    break;
   default:
    string aux = "";
    while (p[i] != ' ')
     aux += string(1, p[i++]);
    pila.push(atof(aux.c_str()));
    i--;
  }
 }
 return pila.top();
}
int main() {
 string s, p;
 cin >> s;
 p = convertir(s);
 cout << "Posfija: " << p << endl;
 cout << "Evaluada: " << evaluar(p) << endl;
 return 0;
}

3 comentarios:

Jose Calderon dijo...

exelente el programa compila perfectamente, has un video para youtube explicando como funciona o cual es el macanismo que sigue el programa te lo agradeseria.

Unknown dijo...

Hola bro, sabes que se puede hacer para que no saque error al colocar una expresion asi: 5** o 6++ como ejemplo

Anónimo dijo...

Casino Bonus Codes | 100+ Casino | Rated by Experts
Latest Casino Bonus choegocasino Codes. 인카지노 Newest Casino Bonus 1xbet Codes, free spins, no deposit bonuses for UK players at CasinoRewards.ca.