<?php
class Calcu
{
const EXP= ['+','-','*','/','(',')'];
public static function calculate($arr){
$outInput = [];
foreach ($arr as $v) {
if (!in_array($v, self::EXP)) {
array_push($outInput, $v);
continue;
}
$a = array_pop($outInput);
$b = array_pop($outInput);
switch ($v) {
case '+':
array_push($outInput, bcadd($a, $b, 2));
break;
case '-':
array_push($outInput, bcsub($b, $a, 2));
break;
case '*':
array_push($outInput, bcmul($b, $a, 2));
break;
case '/':
array_push($outInput, bcdiv($b, $a, 2));
break;
default:
break;
}
}
return count($outInput) == 1 ? $outInput[0] : 0;
}
public static function infixToSuffix($arr)
{
$exps = ['+' => 1, '-' => 1, '*' => 2, '/' => 2, "(" => 0, ")" => 0];
$expStack = [];
$outputQueue = [];
foreach ($arr as $input) {
if (!in_array($input, array_keys($exps))) {
array_push($outputQueue, $input);
continue;
}
if ($input == "(") {
array_push($expStack, $input);
continue;
}
if ($input == ")") {
$tmpExp = array_pop($expStack);
while ($tmpExp && $tmpExp != "(") {
array_push($outputQueue, $tmpExp);
$tmpExp = array_pop($expStack);
}
continue;
}
foreach (array_reverse($expStack) as $exp) {
if ($exps[$input] <= $exps[$exp]) {
array_pop($expStack);
array_push($outputQueue, $exp);
} else {
break;
}
}
array_push($expStack, $input);
}
foreach (array_reverse($expStack) as $exp) {
array_push($outputQueue, $exp);
}
return $outputQueue;
}
public static function strToArray($str)
{
$i = 0;
$tt = '';
$arr = [];
$len = strlen($str);
while($i < $len){
if(in_array(substr($str, $i,1), Self::EXP)){
foreach(Self::EXP as $v){
if($v == substr($str, $i,1)){
if(!empty($tt)){
$arr[] = $tt;
}
$arr[] = substr($str, $i,1);
$tt = '';
}
}
}else{
$tt .= substr($str, $i,1);
if( $len-1 == $i){
$arr[] = $tt;
}
}
$i++;
}
return $arr;
}
public static function init($str)
{
$strArray = self::strToArray($str);
$suffix = self::infixToSuffix($strArray);
return self::calculate($suffix);
}
}