下面我来详细讲解用PHP实现的四则运算表达式计算实现代码的攻略,包括以下几个步骤:
-
获取用户输入的四则运算表达式,并进行合法性检验;
-
将表达式转换为逆波兰表达式(RPN)形式;
-
计算逆波兰表达式,得出最终的计算结果。
接下来我来详细解释每个步骤的具体实现。
1. 获取用户输入的四则运算表达式,并进行合法性检验
首先,我们需要获取用户输入的四则运算表达式,可以使用PHP的内置函数readline()
来实现。获取到表达式后,我们需要对其进行合法性检验,以防止用户输入的表达式不符合预期,导致程序崩溃或出错。具体的检验方法可以包括以下几个步骤:
- 检测表达式中是否只包含数字、括号、加减乘除等符号;
- 检测表达式中括号是否匹配、是否嵌套等;
- 检测表达式中运算符使用是否正确,如相邻运算符是否合法等。
2. 将表达式转换为逆波兰表达式(RPN)形式
接下来,我们需要将表达式转换为逆波兰表达式(RPN)形式。RPN是一种去除了括号和运算符优先级的数学表达式,它由操作数和后缀表达式中的操作符组成。RPN的优点是计算顺序固定,方便计算机计算。具体的转换方法可以使用栈来实现,可以包括以下几个步骤:
- 从左往右遍历表达式中的每个元素,遇到数字就直接输出,遇到运算符就将其压入栈中;
- 如果遇到左括号,则将其压入栈中;
- 如果遇到右括号,则将栈中所有元素依次弹出并输出,直到遇到左括号;
- 如果遇到运算符,则比较其与栈顶元素的优先级,如果栈顶元素优先级低,则将栈顶元素弹出并输出,直到该运算符优先级不低于栈顶元素优先级,然后将该运算符压入栈中。
3. 计算逆波兰表达式,得出最终的计算结果
最后,我们需要对转换后的逆波兰表达式进行计算,得出最终的计算结果。计算方法也可以使用栈来实现,可以包括以下几个步骤:
- 从左往右遍历逆波兰表达式中的每个元素,遇到数字就将其压入栈中;
- 如果遇到运算符,则取出栈顶的两个元素,按照该运算符进行运算,将结果压入栈中;
- 遍历完整个逆波兰表达式后,栈中剩余的元素就是最终的计算结果。
下面是一个用PHP实现四则运算表达式计算的示例代码:
<?php
// 获取用户输入的四则运算表达式
$expr = readline("请输入四则运算表达式:");
// 进行合法性检验(略)
// 将表达式转换为逆波兰表达式(RPN)形式
function toRpn($expr) {
$stack = []; // 运算符栈
$rpn = []; // 逆波兰表达式
// 运算符优先级
$priority = [
'+' => 1,
'-' => 1,
'*' => 2,
'/' => 2,
'(' => 0,
')' => 0,
];
// 遍历表达式中的每个元素
foreach (str_split($expr) as $c) {
if (is_numeric($c)) {
// 如果是数字,直接加入逆波兰表达式
$rpn[] = $c;
} else {
if ($c == '(') {
// 如果是左括号,直接加入运算符栈
array_push($stack, $c);
} elseif ($c == ')') {
// 如果是右括号,弹出运算符栈中的元素,加入逆波兰表达式,直到遇到左括号
while (($s = array_pop($stack)) != '(') {
$rpn[] = $s;
}
} else {
// 如果是运算符,比较其与栈顶元素的优先级,如果栈顶元素优先级低,则弹出栈顶元素加入逆波兰表达式
while (!empty($stack) && $priority[end($stack)] >= $priority[$c]) {
$rpn[] = array_pop($stack);
}
array_push($stack, $c);
}
}
}
// 将栈中剩余的运算符加入逆波兰表达式中
while (!empty($stack)) {
$rpn[] = array_pop($stack);
}
return $rpn;
}
// 计算逆波兰表达式,得出最终的计算结果
function calcRpn($rpn) {
$stack = []; // 数字栈
// 遍历逆波兰表达式中的每个元素
foreach ($rpn as $c) {
if (is_numeric($c)) {
// 如果是数字,直接加入数字栈
array_push($stack, $c);
} else {
// 如果是运算符,取出数字栈顶的两个元素,按照该运算符进行运算,将结果压入数字栈
$b = array_pop($stack);
$a = array_pop($stack);
switch ($c) {
case '+': array_push($stack, $a + $b); break;
case '-': array_push($stack, $a - $b); break;
case '*': array_push($stack, $a * $b); break;
case '/': array_push($stack, $a / $b); break;
}
}
}
// 数字栈中剩余的元素就是最终的计算结果
return array_pop($stack);
}
// 转换为逆波兰表达式
$rpn = toRpn($expr);
// 计算逆波兰表达式,得出最终的计算结果
$result = calcRpn($rpn);
echo "计算结果为:$result\n";
假设用户输入的表达式为3*(4+5)-6/2
,运行以上代码可以得到输出结果为:计算结果为:31
。
本文链接:https://my.lmcjl.com/post/11597.html
展开阅读全文
4 评论