Skip to content

Instantly share code, notes, and snippets.

@razbakov
Last active December 18, 2015 10:29
Show Gist options
  • Save razbakov/5768838 to your computer and use it in GitHub Desktop.
Save razbakov/5768838 to your computer and use it in GitHub Desktop.
<?php
class Math
{
var $operations = array(
'+' => 'plus',
'-' => 'minus',
'*' => 'multiply',
'/' => 'devide',
// add more functions here
);
/**
* Parsing and calculating Reverse Polish notation (RPN)
*
* Example:
* $math = new Math;
* echo $math->parse('1 2 + 4 + 2 * 7 /');
*/
public function parse ($str) {
$stack = array();
$token = strtok($str, ' ');
while ($token !== false)
{
if (in_array($token, array_keys($this->operations)))
{
if (count($stack) < 1) {
throw new Exception("Luck of data in token: '$token'");
} else if (count($stack) > 2) {
$b = array_pop($stack);
} else {
$b = null;
}
$a = array_pop($stack);
$res = $this->calculate($a, $b, $token);
array_push($stack, $res);
} elseif (is_numeric($token))
{
array_push($stack, $token);
} else
{
throw new Exception("Wrong symbol: $token");
}
$token = strtok(' ');
}
if (count($stack) > 1)
throw new Exception("Operators doesn't much operands");
return array_pop($stack);
}
protected function calculate ($a, $b, $operation) {
if (!$operation || !isset($this->operations[$operation])) {
throw new Exception('Operation should be specified');
}
$method = $this->operations[$operation];
try {
if ($b == null) {
$result = $this->$method($a);
} else {
$result = $this->$method($a, $b);
}
} catch (Exception $e) {
throw new Exception($e->getMessage());
}
return $result;
}
protected function plus ($a, $b) {
return $a + $b;
}
protected function minus ($a, $b) {
return $a - $b;
}
protected function devide ($a, $b) {
if ($b == 0) {
throw new Exception ('Devision by zero');
}
return $a / $b;
}
protected function multiply ($a, $b) {
return $a * $b;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment