近期一个小项目需要用到公式运算, 所以就进行一些了解,以下内容均属于个人经验。
在PHP中实现公式表达式四则运算大概有两种方法:
1)使用系统函数eval
2)将表达式转换成逆波兰表达式进行计算。
<?php
//使用系统函数eval
$str = 'L*((k-J)-(C+k))/M';
$param = array('L' => 0.5, 'k' => 2, 'J' => 1, 'C' => 6, 'M' => 4);
$str2 = '';
for($i = 0; $i < strlen($str); $i++) {
$tmp = substr($str, $i, 1);
if (array_key_exists($tmp, $param)) {
$str2 .= $param[$tmp];
} else {
$str2 .= $tmp;
}
}
eval("\$str = $str2;");
printf('%5.2d', $str);
/*End of php*/
<?php
/**
* math_rpn
*
* 实现逆波兰式算法
*
* @author sparkHuang 260558820@qq.com
* @version RPN 1.0.0
*
*/
class math_rpn {
//初始的计算表达式
private $_expression = '';
//处理后的逆波兰表达式
private $_rpnexp = array();
//模拟栈结构的数组
private $_stack = array('#');
//正则判断
//private $_reg = '/^([A-Za-z0-9\(\)\+\-\*\/])*$/';
//优先级
private $_priority = array('#' => 0, '(' => 10, '+' => 20, '-' => 20, '*' => 30, '/' => 30);
//四则运算
private $_operator = array('(', '+', '-', '*', '/', ')');
public function __construct($expression) {
$this->_init($expression);
}
private function _init($expression) {
$this->_expression = $expression;
}
public function exp2rpn() {
$len = strlen($this->_expression);
for($i = 0; $i < $len; $i++) {
$char = substr($this->_expression, $i, 1);
if ($char == '(') {
$this->_stack[] = $char;
continue;
} else if ( ! in_array($char, $this->_operator)) {
$this->_rpnexp[] = $char;
continue;
} else if ($char == ')') {
for($j = count($this->_stack); $j >= 0; $j--) {
$tmp = array_pop($this->_stack);
if ($tmp == "(") {
break;
} else {
$this->_rpnexp[] = $tmp;
}
}
continue;
} else if ($this->_priority[$char] <= $this->_priority[end($this->_stack)]) {
$this->_rpnexp[] = array_pop($this->_stack);
$this->_stack[] = $char;
continue;
} else {
$this->_stack[] = $char;
continue;
}
}
for($i = count($this->_stack); $i >= 0; $i--) {
if (end($this->_stack) == '#') break;
$this->_rpnexp[] = array_pop($this->_stack);
}
return $this->_rpnexp;
}
}
$expression = "(A*(B+C)-E+F)*G";
var_dump($expression);
$mathrpn = new math_rpn($expression);
var_dump($mathrpn->exp2rpn());
/*End of php*/
来源:oschina
链接:https://my.oschina.net/u/167160/blog/33052