<?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"); }