2009-11-26 7 views
2

J'ai besoin d'un moyen de prendre une équation donnée comme une chaîne de caractères et de trouver sa réponse mathématique, le gros problème est que je ne peux pas utiliser eval().Trouver la réponse à l'équation de la chaîne sans utiliser eval()

Je sais que l'équation ne contiendra jamais que des nombres, les quatre opérateurs mathématiques (c'est-à-dire */+ -) et les parenthèses, elle peut avoir ou non des espaces dans la chaîne. Voici quelques exemples.

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

Je suppose que cela va devoir être fait avec une sorte de regex?

+0

formules de chaîne L'évaluation est assez facile quand ils sont aussi simple que cela. Voir une demi-douzaine de réponses à http://stackoverflow.com/questions/1384811/code-golf-mathematical-expression-evaluator-full-pemdas –

Répondre

9

Les expressions mathématiques ne sont pas régulières. Ils sont context-free.

Votre meilleur pari est de les analyser en utilisant des algorithmes d'analyse mathématique bien connus comme . Tout ce que vous avez à faire est de mettre en application l'algorithme en PHP. Vous pourriez même être en mesure de trouver des implémentations PHP en ligne.

+1

Il est incroyable de voir combien on peut apprendre en lisant simplement les réponses aux questions! C'est nouveau pour moi, cool! +1 – Ben

+1

Cela vous donnera un bon départ: '$ tokens = token_get_all ('

4

Juste au cas où quelqu'un se intéresse est l'algorithme ici, je suis venu avec en PHP pour la production de notation polonaise inversée

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; 
} 
Questions connexes