SHOW:
|
|
- or go back to the newest paste.
| 1 | <?php | |
| 2 | ||
| 3 | function tokenize($expr) {
| |
| 4 | - | preg_match_all('/(?:-|)\d+|\+|-|\*|\/|\(|\)/', $expr, $match);
|
| 4 | + | preg_match_all('/(?:-|)\d+|\+|-|\*|\^|\/|\(|\)/', $expr, $match);
|
| 5 | $match = $match[0]; | |
| 6 | $tokens = array(); | |
| 7 | $stack = array(); | |
| 8 | - | $precedence = array('+' => 1, '-' => 1, '*' => 2, '/' => 2);
|
| 8 | + | $precedence = array('+' => 2, '-' => 2, '*' => 3, '/' => 3, '^' => 4);
|
| 9 | ||
| 10 | while($match) {
| |
| 11 | $token = array_shift($match); | |
| 12 | ||
| 13 | if(is_numeric($token)) {
| |
| 14 | array_push($tokens, $token); | |
| 15 | continue; | |
| 16 | - | else {
|
| 16 | + | |
| 17 | - | if($token === ')') {
|
| 17 | + | |
| 18 | - | while($stack && end($stack) !== '(') {
|
| 18 | + | if($token === ')') {
|
| 19 | - | array_push($tokens, array_pop($stack)); |
| 19 | + | while($stack && end($stack) !== '(') {
|
| 20 | - | } |
| 20 | + | |
| 21 | - | |
| 21 | + | |
| 22 | - | array_pop($stack); |
| 22 | + | |
| 23 | - | continue; |
| 23 | + | array_pop($stack); |
| 24 | continue; | |
| 25 | } | |
| 26 | - | while($token !== '(' && ($stack && end($stack) !== '(') && $precedence[$token] < $precedence[end($stack)]) {
|
| 26 | + | |
| 27 | while($token !== '(' && ($stack && end($stack) !== '(') && $precedence[$token] < $precedence[end($stack)]) {
| |
| 28 | array_push($tokens, array_pop($stack)); | |
| 29 | } | |
| 30 | - | array_push($stack, $token); |
| 30 | + | |
| 31 | array_push($stack, $token); | |
| 32 | } | |
| 33 | ||
| 34 | return array_merge($tokens, array_reverse($stack)); | |
| 35 | } | |
| 36 | ||
| 37 | function resolve($math) {
| |
| 38 | $funcs = array( | |
| 39 | '+' => function ($left, $right) { return $left + $right; },
| |
| 40 | '-' => function ($left, $right) { return $left - $right; },
| |
| 41 | '/' => function ($left, $right) { return $left / $right; },
| |
| 42 | - | '*' => function ($left, $right) { return $left * $right; }
|
| 42 | + | '*' => function ($left, $right) { return $left * $right; },
|
| 43 | '^' => 'pow' | |
| 44 | ); | |
| 45 | ||
| 46 | $stack = array(); | |
| 47 | ||
| 48 | while(count($math) > 1) {
| |
| 49 | $token = array_shift($math); | |
| 50 | ||
| 51 | if(!is_numeric($token)) {
| |
| 52 | $token = $funcs[$token](array_shift($math), array_shift($math)); | |
| 53 | } | |
| 54 | ||
| 55 | array_push($stack, $token); | |
| 56 | } | |
| 57 | ||
| 58 | return $stack[0]; | |
| 59 | } | |
| 60 | ||
| 61 | - | $math = tokenize('2*3+4*(5 - 6)');
|
| 61 | + | |
| 62 | $math = tokenize('3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3');
| |
| 63 | echo implode(' ', $math) . PHP_EOL;
| |
| 64 | echo resolve($math); | |
| 65 | ||
| 66 | ?> |