用链栈实现简易四则运算计算器(php版)

39次阅读

共计 2571 个字符,预计需要花费 7 分钟才能阅读完成。

栈是一种限定仅在表尾进行插入和删除操作的线性表。栈的应用有很多,比如常见的递归,计算机表达式求值等。下面我们用栈来实现简易的四则运算计算器。
列一下本文的思路:

实现链栈的数据结构及其操作
中缀表达式转后缀表达式
后缀表达式求值

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();
得到的结果如下:

简易的计算器就实现啦!~~~(代码中有一些细节未做判断,希望读者理解。欢迎大家提出批评修改意见,感谢~)

正文完
 0