Heim >Backend-Entwicklung >PHP-Tutorial >Wie erstellt man einen PHP-Rechner mit dem Shunting-Yard-Algorithmus?

Wie erstellt man einen PHP-Rechner mit dem Shunting-Yard-Algorithmus?

DDD
DDDOriginal
2024-12-07 18:52:16816Durchsuche

How to Build a PHP Calculator Using the Shunting-Yard Algorithm?

So erstellen Sie einen Rechner in PHP

Problem:

Erstellen Sie einen PHP-Rechner, der einfache eingegebene algebraische Ausdrücke auswerten kann von Benutzern in algebraischer Standardnotation, einschließlich Ausdrücken mit Klammern.

Gemeinsamer Ansatz:

Eine ineffiziente, aber vorübergehende Lösung besteht darin, Ausdrücke in einer Zeichenfolgendarstellung des Ausdrucks zu ersetzen, wie zum Beispiel:

for ($a=1; $a < 1000; $a++) {
    for ($b=1; $b < 1000; $b++) {
        string_replace($a . '*' . $b, $a*$b, $string);
    }
}

Rangierbahnhof-Algorithmus:

Ein effizienterer Ansatz ist die Verwendung von Rangierbahnhof-Algorithmus.

Implementierung:

Terminalausdrücke (Werte und Operatoren):

abstract class TerminalExpression {
    protected $value = '';

    public static function factory($value) {
        // Create terminal expressions based on the provided value (number, operator, or parenthesis)
    }

    abstract public function operate(Stack $stack);
}

class Number extends TerminalExpression {
    public function operate(Stack $stack) {
        return $this->value;
    }
}

class Operator extends TerminalExpression {
    protected $precidence = 0;
    protected $leftAssoc = true;

    public function getPrecidence() {
        return $this->precidence;
    }

    public function isLeftAssoc() {
        return $this->leftAssoc;
    }
}

class Addition extends Operator {
    protected $precidence = 4;
}

class Subtraction extends Operator {
    protected $precidence = 4;
}

class Multiplication extends Operator {
    protected $precidence = 5;
}

class Division extends Operator {
    protected $precidence = 5;
}

class Parenthesis extends TerminalExpression {
    protected $precidence = 7;

    public function isParenthesis() {
        return true;
    }
}

Stapel Implementierung:

class Stack {
    protected $data = [];
    public function push($element) {
        array_push($this->data, $element);
    }
    public function pop() {
        return array_pop($this->data);
    }
}

Mathe-Klasse (Executor):

class Math {
    protected $variables = [];

    public function evaluate($string) {
        $stack = $this->parse($string);
        return $this->run($stack);
    }

    public function parse($string) {
        // Tokenize expression
        $tokens = array_map('trim', preg_split('((\d+|\+|-|\(|\)|\*|/)|\s+)', $string, null, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE));

        // Parse operators and parentheses using the Shunting Yard algorithm
        $output = new Stack();
        $operators = new Stack();

        foreach ($tokens as $token) {
            $expression = TerminalExpression::factory($token);

            if ($expression->isOperator()) {
                $this->parseOperator($expression, $output, $operators);
            } elseif ($expression->isParenthesis()) {
                $this->parseParenthesis($expression, $output, $operators);
            } else {
                $output->push($expression);
            }
        }

        // Pop remaining operators on stack and push to output
        while (($op = $operators->pop()) &amp;&amp; $op->isOperator()) {
            if ($op->isParenthesis()) {
                throw new RuntimeException('Mismatched Parenthesis');
            }
            $output->push($op);
        }

        return $output;
    }

    public function run(Stack $stack) {
        // Evaluate stack and return result
        while (($operator = $stack->pop()) &amp;&amp; $operator->isOperator()) {
            $value = $operator->operate($stack);
            $stack->push(TerminalExpression::factory($value));
        }

        return $operator ? $operator->render() : $this->render($stack);
    }

    protected function extractVariables($token) {
        if ($token[0] == '$') {
            $key = substr($token, 1);
            return isset($this->variables[$key]) ? $this->variables[$key] : 0;
        }
        return $token;
    }

    // ...
}

Mit dieser Implementierung können Sie Ausdrücke wie folgt auswerten:

$math = new Math();
$answer = $math->evaluate('(2 + 3) * 4'); // 20
$answer = $math->evaluate('1 + 2 * ((3 + 4) * 5 + 6)'); // 83
$answer = $math->evaluate('(1 + 2) * (3 + 4) * (5 + 6)'); // 231
$math->registerVariable('a', 4);
$answer = $math->evaluate('($a + 3) * 4'); // 28

Das obige ist der detaillierte Inhalt vonWie erstellt man einen PHP-Rechner mit dem Shunting-Yard-Algorithmus?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn