<?php
namespace app\controller;
use app\BaseController;
class Anti extends BaseController
{
private $operatorAdd = '+';
private $operatorReduce = '-';
private $operatorRide = '*';
private $operatorExcept = '/';
private $left = '(';
private $right = ')';
/**
* 存放数字
* @var string
*/
private $bucket = array();
/**
* 存放表达式
*/
private $operatorBucket = array();
public function execute()
{
// 转换工具 http://tools.jb51.net/jisuanqi/exp_jisuanqi
try{
$operator = [
// '9', '+', '(', '3', '-', '1', ')', '*', '3', '+', '10', '/', '2'
// '9', '+', '(', '5', '-', '3', ')', '*', '2', '+', '9', '/', '3',
'9', '+', '(', '20','-','(', '5', '-', '3', ')', '*', '3',')', '*', '2', '+', '9', '/', '32', '+', '2', '/', '2'
// '1', '+', '2', '-', '8'
];
// 9+(5-3)*2+9/3
// 9+(20-(5-3)*3)*2+9/32+2/2
// 将运算符转化为 后缀表达式
var_dump($this->toAntiPoland($operator));
// // 运算
// $result = 0;
// for ($i=0; $i < count($this->bucket); $i++) {
// if(in_array($this->bucket[$i], [
// $this->operatorAdd,
// $this->operatorReduce,
// $this->operatorRide,
// $this->operatorExcept,
// $this->left, $this->right])
// ) {
// $l = $this->bucket[$i-2];
// $r = $this->bucket[$i-1];
// switch ($this->bucket[$i]) {
// case '+':
// $num = $l+$r;
// break;
// case '-':
// $num = $l-$r;
// break;
// case '*':
// $num = $l*$r;
// break;
// case '/':
// if($r <= 0) {
// throw new \Exception("表达式错误!除数不能为0", 1);
// }
// $num = $l/$r;
// break;
// }
// unset($this->bucket[$i-2]);
// unset($this->bucket[$i-1]);
// $this->bucket[$i] = $num;
// $this->bucket = array_values($this->bucket);
// $i=0;
// if(count($this->bucket) <= 1) {
// $result = array_pop($this->bucket);
// break;
// }
// }
// }
// var_dump($result);die;
} catch(\Exception $e) {
exit($e->getMessage());
}
}
/**
* 中缀表达式 转 后缀表达式
*/
public function toAntiPoland($operator)
{
foreach ($operator as $key => $value) {
// 判断是否运算符
if(in_array($value, [$this->operatorAdd, $this->operatorReduce, $this->operatorRide, $this->operatorExcept, $this->left, $this->right])) {
if($value === $this->right) {
// 查找第一个( 出现的位置
$leftFirstKey = $this->strLastKey($this->left);
for ($i=count($this->operatorBucket)-1; $i >= $leftFirstKey ; $i--) {
if(!in_array( $this->operatorBucket[$i], [$this->left, $this->right])) {
if($this->operatorBucket[$i] == $this->left) {
break;
}
$this->bucket[] = $this->operatorBucket[$i];
}
unset($this->operatorBucket[$i]);
}
}else{
// 运算符比较
if(!empty($this->searchLastOper()) && !in_array($value, [$this->left, $this->right]) && $this->priority($this->searchLastOper()) > $this->priority($value) ) {
while (!empty($this->operatorBucket)) {
$e = array_pop($this->operatorBucket);
if($e == $this->left) {
break;
}
$this->bucket[] = $e;
}
}
$this->operatorBucket[] = $value;
}
}else{
$this->bucket[] = $value;
}
$this->operatorBucket = array_values($this->operatorBucket);
}
// 取出全部运算符
while (!empty($this->operatorBucket)) {
$this->bucket[] = array_pop($this->operatorBucket);
}
return $this->bucket;
}
/**
* 寻找栈中最后一个运算符出现的位置 不包含 ()
*/
private function searchLastOper()
{
try{
$this->operatorBucket = array_values($this->operatorBucket);
for ($i=count($this->operatorBucket) - 1; $i >=0 ; $i--) {
if(!in_array($this->operatorBucket[$i], [$this->left, $this->right])) {
return $this->operatorBucket[$i];
}
}
return '';
}catch(\Exception $e){
var_dump($this->operatorBucket);die;
}
}
/**
* 寻找最后一个 ( 出现的位置
*
* @param str string
* @return
*/
private function strLastKey($str)
{
for($i=count($this->operatorBucket) - 1; $i>=0; $i--) {
if($this->operatorBucket[$i] == $str) {
return $i;
}
}
throw new \Exception("错误的表达式,()应该成对出现", 1);
// return false;
}
/**
* 运算符优先级
*/
private function priority($operator='')
{
$data = [
$this->operatorRide => 10,
$this->operatorExcept => 10,
$this->operatorAdd => 5,
$this->operatorReduce => 5,
$this->left => 1,
$this->right => 1
];
if(!isset($data[$operator])) {
throw new \Exception("错误的表达式!". $operator, 1);
}
return $data[$operator];
}
}
PHP 中缀表达式转后缀表达式
最新推荐文章于 2024-08-22 21:28:55 发布