Pregunta

Necesito una forma de tomar una ecuación dada como una cadena y encontrar su respuesta matemática, la gran advertencia es que no puedo usar eval ().

Sé que la ecuación solo contendrá números, los cuatro operadores matemáticos (es decir, * / + -) y paréntesis, puede o no tener espacios en la cadena. Aquí hay un par de ejemplos.

4 * 4
4+6/3
(3 / 2)*(4+8)
(4+8) * 2

¿Supongo que se tendrá que hacer con algún tipo de expresión regular?

¿Fue útil?

Solución

Las expresiones matemáticas no son regulares. Son libre de contexto .

Tu mejor apuesta es analizarlos usando algoritmos de análisis matemático conocidos como el algoritmo de derivación de yardas . Todo lo que tiene que preocuparse es implementar el algoritmo en PHP. Incluso podrías encontrar implementaciones de PHP en línea.

Otros consejos

En caso de que alguien esté interesado aquí es el algoritmo que se me ocurrió en PHP para producir la notación polaca inversa

function convertToRPN($equation)

{
    $equation = str_replace(' ', '', $equation);
    $tokens = token_get_all('<?php ' . $equation);
    $operators = array('*' => 1, '/' => 1, '+' => 2, '-' => 2);
    $rpn = '';
    $stack = array();
    $size = count($tokens);                                                 
    for($i = 1; $i < $size; $i++) {
        if(is_array($tokens[$i])) {
            $rpn .= $tokens[$i][1] . ' ';
        } else {
            if(empty($stack) || $tokens[$i] == '(') {
                $stack[] = $tokens[$i];
            } else {
                if($tokens[$i] == ')') {
                    while(end($stack) != '(') {
                        $rpn .= array_pop($stack);
                    }
                    array_pop($stack);
                } else {
                    while(!empty($stack) && end($stack) != '(' && $operators[$tokens[$i]] >= $operators[end($stack)]) {
                        $rpn .= array_pop($stack);
                    }
                    $stack[] = $tokens[$i];
                }
            }
        }
    }

    while(!empty($stack)) {
        $rpn .= array_pop($stack);
    }

    return $rpn;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top