Evaluación de Expresiones Aritméticas en Notación Polaca Inversa con Pila

Para evaluar una expresión aritmética en Notación Polaca Inversa (RPN), se utiliza una estructura de datos de pila, lo que permite un procesamiento efiicente con operaciones básicas de apilar y desapilar.

La Notación Polaca Inversa, o notación posfija, coloca los operadores después de sus operandos, introducida por el lógico polaco J. Lukasiewciz en 1929. Su principal ventaja es simplificar la evaluación mediante un algoritmo directo: recorrer la expresión, apilar operandos y, al encontrar un operador, desapilar dos operandos, aplicar la operación y apilar el resultado.

Ejemplos de evaluación:

  • ["2", "1", "+", "3", "*"] → ((2 + 1) * 3) → 9
  • ["4", "13", "5", "/", "+"] → (4 + (13 / 5)) → 6

El enfoque implementado usa una pila para almacenar operendos y operar según los operadores encontrados. Se requiere conversión entre cadenas y enteros para manejar los operandos.

A continuación, un ejemplo en C++ con nombres de variables y funciones modificados para reducir similitud:


class ProcesadorRPN {
public:
    int evaluar(const vector<string>& expresion) {
        stack<int> almacen;
        for (const string& elemento : expresion) {
            if (esOperador(elemento)) {
                int segundo = almacen.top(); almacen.pop();
                int primero = almacen.top(); almacen.pop();
                almacen.push(aplicarOperacion(primero, segundo, elemento));
            } else {
                almacen.push(convertirCadena(elemento));
            }
        }
        return almacen.top();
    }

private:
    bool esOperador(const string& s) {
        return s == "+" || s == "-" || s == "*" || s == "/";
    }

    int aplicarOperacion(int a, int b, const string& operador) {
        if (operador == "+") return a + b;
        if (operador == "-") return a - b;
        if (operador == "*") return a * b;
        if (operador == "/") return a / b;
        return 0;
    }

    int convertirCadena(const string& s) {
        int valor = 0;
        int signo = 1;
        size_t inicio = 0;
        if (s[0] == '-') {
            signo = -1;
            inicio = 1;
        }
        for (size_t i = inicio; i < s.size(); ++i) {
            valor = valor * 10 + (s[i] - '0');
        }
        return signo * valor;
    }
};
</int></string>

Otra implementación simplifica la detección de operadores usando un switch basado en el primer carácter:


class EvaluadorRPN {
public:
    int calcular(vector<string>& tokens) {
        stack<int> pila;
        for (auto tok : tokens) {
            if (tok.size() > 1 || isdigit(tok[0])) {
                pila.push(stoi(tok));
            } else {
                int y = pila.top(); pila.pop();
                int x = pila.top(); pila.pop();
                int resultado;
                switch (tok[0]) {
                    case '+': resultado = x + y; break;
                    case '-': resultado = x - y; break;
                    case '*': resultado = x * y; break;
                    case '/': resultado = x / y; break;
                    default: resultado = 0;
                }
                pila.push(resultado);
            }
        }
        return pila.top();
    }
};
</int></string>

Un método más conciso utiliza una verificación directa de dígitos y operaciones aritméticas en lugar de funciones auxiliares:


class SolucionRPN {
public:
    int evaluar(vector<string>& expr) {
        stack<int> datos;
        for (auto s : expr) {
            if (s.length() > 1 || isdigit(s[0])) {
                datos.push(stoi(s));
            } else {
                int op2 = datos.top(); datos.pop();
                int op1 = datos.top(); datos.pop();
                switch (s[0]) {
                    case '+': op1 += op2; break;
                    case '-': op1 -= op2; break;
                    case '*': op1 *= op2; break;
                    case '/': op1 /= op2; break;
                }
                datos.push(op1);
            }
        }
        return datos.top();
    }
};
</int></string>

Etiquetas: notación polaca inversa pila C++ evaluación de expresiones conversión de cadenas

Publicado el 6-24 23:32