<?php
/**
* 计算表达式思路
* 1+2*3-2
* 思路:
* 1、扫描每个字符
* 2、判断是否运算符和数字
* 3、数字直接进栈
* 4、运算符
* 1、第一个运算符直接入栈
* 2、N个运算符要与之前运算符比较
* 1、如果当前运算符大于栈顶的运算符
* 1、从数栈取出两个数字进行运算,其实这个就是优先级运算
* 2、把结果入栈
* 2、如果不大于直接入栈
* 5、得到平级运算表达式
* 6、遍历运算符出栈进行运算,然后在入栈,一直到运算符为空。
* @author wangdk
*
*/
class Expression
{
public $numArray = array();
public $operArray = array();
/**
* 判断是否为数字
*/
public function isNumeric($str) {
return is_numeric($str);
}
/**
* 判断是否为运算符
*/
public function isOperation($str) {
if ($str == '+' || $str == '-') {
return 1;
}
if ($str == '*' || $str == '/') {
return 2;
}
return 0;
}
/**
* 根据运算符进行运算
*/
public function calc($ch, $numA, $numB) {
$result = 0;
switch($ch) {
case '+':
$result = $numA + $numB;
break;
case '-':
$result = $numB - $numA;
break;
case '*':
$result = $numA * $numB;
break;
case '/':
$result = $numB / $numA;
break;
}
return $result;
}
/**
* 扫描表达式进行入栈
*/
public function getResult($str) {
$count = strlen($str);
for ($i = 0; $i < $count; $i++) {
// 数字直接入栈
if ($this->isNumeric($str[$i])) {
array_push($this->numArray, $str[$i]);
} else {
// 第一个运算符直接入栈
if (empty($this->operArray)) {
$this->operArray[] = $str[$i];
} else {
// 多个运算符开始比较,去掉优先级
$operArrayCopy = $this->operArray;
$prev_operation = array_pop($operArrayCopy);
// 如果当前运算符号小于 上一个运算符
if ($this->isOperation($str[$i]) <= $this->isOperation($prev_operation)) {
// 运算
$prev_operation = array_pop($this->operArray);
$first_num = array_pop($this->numArray);
$second_num = array_pop($this->numArray);
$result = $this->calc($prev_operation, $first_num, $second_num);
$this->numArray[] = $result;
array_push($this->operArray, $str[$i]);
} else {
array_push($this->operArray, $str[$i]);
}
}
}
}
// 遍历平级运算符,进行运算
$operArrayCount = count($this->operArray);
while($operArrayCount) {
$prev_operation = array_pop($this->operArray);
$first_num = array_pop($this->numArray);
$second_num = array_pop($this->numArray);
$result = $this->calc($prev_operation, $first_num, $second_num);
$this->numArray[] = $result;
$operArrayCount = count($this->operArray);
}
}
}
$e = new Expression();
$e->getResult('1+2*3+4*8');
echo '<pre>';
print_r($e->numArray);
print_r($e->operArray)
?>
转载于:https://my.oschina.net/wangdk/blog/158787