<?php
$str = "(1 + 2) * 3";
$res = calc_str2($str);
echo $res."\n";
function calc_str2($str){
$stack = [];
$polish = [];
while ($str != ""){
$t = get($str);
if ($t == '(') {
$stack[] = $t;
continue;
}
if ($t == ')') {
while (count($stack) > 0){
$s_top = array_pop($stack);
if ($s_top == '(') break;
$polish[] = $s_top;
}
continue;
}
while (count($stack) > 0){
$s_top = $stack[count($stack)-1];
if(priority($t) > priority($s_top)) break;
$polish[] = array_pop($stack);
}
$stack[] = $t;
}
while(count($stack) > 0) $polish[] = array_pop($stack);
echo "[".implode(" ", $polish)."]\n";
foreach ($polish as $t){
if (preg_match('#^\d+$#', $t)){
$tack[] = intval($t); continue;
}
$b = array_pop($stack);
$a = array_pop($stack);
switch ($t){
case '+': $c = $a + $b; break;
case '-': $c = $a - $b; break;
case '*': $c = $a * $b; break;
case '/': $c = $a / $b; break;
default: throw new Exception("未知の文字:$t");
}
$stack[] = $c;
}
return array_pop($stack);
}
function priority($c){
$pri = ['num'=>3, '*'=>2, '/'=>2, '+'=>1, '-'=>1, '('=>0];
return isset($pri[$c]) ? $pri[$c] : $pri['num'];
}
function get(&$str){
$str = trim($str);
$c = substr($str, 0, 1);
if (strpos("()+-*/", $c) !== false){
$str = substr($str, 1);
return $c;
}
if (preg_match('#^(\d+)#', $str, $m)){
$str = substr($str, strlen($m[1]));
return $m[1];
}
throw new Exception("未知の文字: $c");
}