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:
- Data structure and operation of chain stack
- Infix expression to suffix expression
- 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