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
Freigeben: 2024-12-07 18:52:16
Original
820 Leute haben es durchsucht

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);
    }
}
Nach dem Login kopieren

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;
    }
}
Nach dem Login kopieren

Stapel Implementierung:

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

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

    // ...
}
Nach dem Login kopieren

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
Nach dem Login kopieren

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!

Quelle:php.cn
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage