HTML代码:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h1>高级计算器</h1>
请输入运算表达式:
<br/><input type="text" name="exp" value=""><button class="">计算</button>
<br/>计算结果是:<b></b>
</body>
</html>
<script src="./jquery.min.js"></script>
<script>
$(function(){
$('button').click(function(){
var exp = $('input').val();
$.ajax({
url: 'exp.php',
data:{
'exp':exp
},
type:'post',
dataType:'json',
success:function(res){
$('b').text(res.data)
}
})
})
})
</script>
php代码:
<?php
$exp = isset($_POST['exp']) ? $_POST['exp'] : '';
if (empty($exp)) return;
/**
*3+2*6-7
* 60+5*10-70
* 5*5*3-5+1/2*4-6
*/
//数字栈
$num_arr = [];
//运算符号栈
$oper_arr = [];
//$exp = '3+6*2-7';
$len = strlen($exp);
$temp_str = '';
for ($i = 0; $i < $len; $i++) {
if (isOper($exp[$i])) {
/**
* 1.如果运算符栈为空,就直接入栈
* 2.如果不为空,判断优先级:
* 2.1 如果当前运算符小于等于栈顶运算符优先级,就直接用栈顶运算符计算,并且把计算结果入数字栈,然后把当前符号入符号栈
* 2.2 如果当前运算符大于符号栈顶运算符,就直接入栈
*/
//判断符号栈是否空
if (count($oper_arr) == 0) { //空
//入符号栈
array_push($oper_arr, $exp[$i]);
} else {
//当前符号级别
$exp_level = get_level($exp[$i]);
//栈顶符号级别
while (count($oper_arr) != 0 && $exp_level <= get_level($oper_arr[count($oper_arr) - 1])) {
//直接用栈顶符号计算
$res = calc($num_arr, $oper_arr);
//再把计算出的结果入数字栈
array_push($num_arr, $res);
}
//跳出循环后,入符号栈
array_push($oper_arr, $exp[$i]);
}
} else {
$temp_str .= $exp[$i];
//如果是字符串最后一个,就直接入栈
if ($i + 1 == $len) {
array_push($num_arr, $temp_str);
} else {
//数字,数字栈
if(isOper($exp[$i+1])){
array_push($num_arr, $temp_str);
$temp_str = '';
}
}
}
}
//最后一步运算数字栈和符号栈剩余的
$res = calc($num_arr, $oper_arr);
echo json_encode(['data' => $res]);
die;
//判断字符串是否为运算符
function isOper($val)
{
if ($val == '+' || $val == '-' || $val == '*' || $val == '/') {
return true;
}
return false;
}
/*
*判断运算符的级别
*/
function get_level($val)
{
if ($val == '*' || $val == '/') {
return 2;
} else if ($val == '+' || $val == '-') {
return 1;
}
}
/**
* 数字运算
* @param $num_arr 数字栈
* @param $oper_arr 符号栈
* @return float|int|mixed
*/
function calc(&$num_arr, &$oper_arr)
{
$val2 = array_pop($num_arr);
$val1 = array_pop($num_arr);
$oper = array_pop($oper_arr);
switch ($oper) {
case '+':
return $val1 + $val2;
break;
case '-':
return $val1 - $val2;
break;
case '*':
return $val1 * $val2;
break;
case '/':
return $val1 / $val2;
break;
}
}