用链栈实现简易四则运算计算器(php版)
栈是一种限定仅在表尾进行插入和删除操作的线性表。栈的应用有很多,比如常见的递归,计算机表达式求值等。下面我们用栈来实现简易的四则运算计算器。
列一下本文的思路:
- 实现链栈的数据结构及其操作
- 中缀表达式转后缀表达式
- 后缀表达式求值
1、首先, 先实现一个链栈。
//定义栈的数据结构 class Node { public $symbol; public $next; public function __construct( $symbol, $next ) { $this->symbol = $symbol; $this->next = $next; } } //初始化栈,生成头结点 function initStack( &$node ) { $node = new Node( '', null ); } //入栈 function push( Node &$node, $symbol ) { $p = new Node( $symbol, null ); $p->next = $node->next; $node->next = $p; } //出栈 function pop( Node &$node, &$symbol ) { if ( null == $node->next ) { echo "栈空\n"; return; } $q = $node->next; $symbol = $q->symbol; $node->next = $node->next->next; unset( $q ); }
2、其次, 利用第一步实现的链栈,将中缀表达式转为后缀表达式。
//获取运算符的优先级 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; } //栈顶依次出栈,如果遇到'('则停止 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; } //中缀表达式转后缀表达式 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 ) ) { //数字直接输出 $back_expression .= $symbol; } else {//非数字则比较优先级 $stack_top_priority = get_priority( null == $list->next ? '' : $list->next->symbol ); $current_symbol_priority = get_priority( $symbol ); if ( $current_symbol_priority > $stack_top_priority ) {//优先级比栈顶高则进栈 push( $list, $symbol ); } else { $output = clear_stack( $list ); $back_expression .= $output; if ( ')' != $symbol ) { push( $list, $symbol ); } } } } } while ( null != $list->next ) {//将栈清空 pop( $list, $item ); $back_expression .= $item; } return $back_expression; }
3、接下来, 我们利用第一步实现的链栈,和第二步得到的后缀表达式,计算最后的值。
//是否是四则运算符号 function is_arithmetic_symbol( $symbol ) { $arithmetic_symbols = array( '+', '-', '*', '/' ); if ( in_array( $symbol, $arithmetic_symbols ) ) { return true; } else { return false; } } //计算后缀表达式的值 function calculate( $expression ) { $stack = new Node( '', null ); $length = strlen( $expression ); for ( $i = 0; $i < $length; $i ++ ) { if ( ' ' != $expression[ $i ] ) {//为空则跳过 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; }
最后,我们测试一下所实现的计算器。
function main() { $back_expression = middle_to_back( '((1+2)*3-4) * 5' ); $result = calculate( $back_expression ); echo "后缀表达式的值为: " . $back_expression, PHP_EOL; echo "result : " . $result, PHP_EOL; } main();
得到的结果如下:
简易的计算器就实现啦!~~~
(代码中有一些细节未做判断,希望读者理解。欢迎大家提出批评修改意见,感谢~)
相关推荐
zhiliang 2020-01-31
roseying 2019-12-01
帕尼尼 2014-01-13
星愿 2019-11-16
85397518 2019-11-16
getianao 2019-11-16
hyv 2014-01-13
袁萌 2017-10-01
xiaohao 2011-04-06
drilistbox 2019-04-25
pythoncream 2016-02-27
LHpython 2019-04-08
吴家应 2014-03-10
PHP100 2019-03-28
PHP100 2019-03-27
明学的白板 2018-05-20
锦妖和她的小伙伴们 2018-04-19