Using chain stack to realize simple four arithmetic calculators (php version)

Keywords: PHP calculator

A stack is a linear table that can only be inserted and deleted at the end of a table. There are many applications of stack, such as common recursion, computer expression evaluation and so on. Next we use the stack to realize the simple four arithmetic calculators.

Here are the ideas of this article:

  1. Data structure and operation of chain stack
  2. Infix expression to suffix expression
  3. Suffix expression evaluation
1. First, implement a chain stack.
//Define the data structure of the stack
class Node
{
    public $symbol;
    public $next;

    public function __construct( $symbol, $next )
    {
        $this->symbol = $symbol;
        $this->next   = $next;
    }
}

//Initialize stack, generate header node
function initStack( &$node )
{
    $node = new Node( '', null );
}

//Push
function push( Node &$node, $symbol )
{
    $p          = new Node( $symbol, null );
    $p->next    = $node->next;
    $node->next = $p;
}

//Stack out
function pop( Node &$node, &$symbol )
{
    if ( null == $node->next ) {
        echo "Stack space\n";

        return;
    }

    $q          = $node->next;
    $symbol     = $q->symbol;
    $node->next = $node->next->next;
    unset( $q );
}
2. Secondly, the infix expression is transformed into a suffix expression by using the chain stack implemented in the first step.
//Get priority of operator
function get_priority( $symbol )
{
    switch ( $symbol ) {
        case '(':
            $priority = 3;
            break;
        case '*':
        case '/':
            $priority = 2;
            break;
        case '+':
        case '-':
            $priority = 1;
            break;
        case ')':
            $priority = 0;
            break;
        default:
            $priority = 0;
            break;
    }

    return $priority;
}

//The top of the stack will be out of the stack in turn. If '(' is encountered, it will stop
function clear_stack( &$list )
{
    $res = '';
    while ( null != $list->next ) {
        if ( '(' != $list->next->symbol ) {
            pop( $list, $item );
            $res .= $item;

        } else {
            pop( $list, $item );

            return $res;
        }
    }

    return $res;
}

//Infix expression to suffix expression
function middle_to_back( $middle_expression )
{
    initStack( $list );
    $back_expression = '';
    $length          = strlen( $middle_expression );
    for ( $i = 0; $i < $length; $i ++ ) {
        $symbol = $middle_expression[ $i ];
        if ( ' ' != $symbol ) {
            if ( is_numeric( $symbol ) ) { //Digital direct output
                $back_expression .= $symbol;
            } else {//Non numeric comparison priority
                $stack_top_priority      = get_priority( null == $list->next ? '' : $list->next->symbol );
                $current_symbol_priority = get_priority( $symbol );
                if ( $current_symbol_priority > $stack_top_priority ) {//Higher priority than the top of the stack
                    push( $list, $symbol );
                } else {
                    $output          = clear_stack( $list );
                    $back_expression .= $output;
                    if ( ')' != $symbol ) {
                        push( $list, $symbol );
                    }
                }
            }
        }
    }

    while ( null != $list->next ) {//Empty the stack
        pop( $list, $item );
        $back_expression .= $item;
    }

    return $back_expression;
}
3. Next, we use the chain stack implemented in the first step and the suffix expression obtained in the second step to calculate the final value.
//Are they four operation symbols
function is_arithmetic_symbol( $symbol )
{
    $arithmetic_symbols = array( '+', '-', '*', '/' );
    if ( in_array( $symbol, $arithmetic_symbols ) ) {
        return true;
    } else {
        return false;
    }
}

//Evaluate the value of a suffix expression
function calculate( $expression )
{
    $stack  = new Node( '', null );
    $length = strlen( $expression );
    for ( $i = 0; $i < $length; $i ++ ) {
        if ( ' ' != $expression[ $i ] ) {//Skip if it is empty
            if ( is_numeric( $expression[ $i ] ) ) {
                push( $stack, $expression[ $i ] );
            } else if ( is_arithmetic_symbol( $expression[ $i ] ) ) {
                pop( $stack, $n1 );
                pop( $stack, $n2 );
                $res = get_result( $n2, $n1, $expression[ $i ] );
                push( $stack, $res );
            } else {
                echo "wrong symbol, exit";
                exit();
            }
        }
    }

    $value = $stack->next->symbol;

    return $value;
}
Finally, let's test the implemented calculator.
function main()
{
    $back_expression = middle_to_back( '((1+2)*3-4) * 5' );
    $result          = calculate( $back_expression );
    echo "The value of the suffix expression is: " . $back_expression, PHP_EOL;
    echo "result : " . $result, PHP_EOL;
}

main();

The results are as follows:

Simple calculator will be realized! ~ ~
(there are some details in the code that have not been judged. I hope the readers can understand them. Thank you for your comments

Posted by TalonFinsky on Mon, 02 Dec 2019 20:48:24 -0800