fork(1) download
  1. <?php
  2.  
  3. function isPossible($toCheck){
  4. $toCheck=substr($toCheck, 1, -1);
  5. $pars = 0;
  6. for($i=0; $i<strlen($toCheck); $i++){
  7. if($toCheck[$i]=="(") $pars++;
  8. if($toCheck[$i]==")") $pars--;
  9. if($pars<0) return false;
  10. }
  11. return true;
  12. }
  13.  
  14. function trimpars($toTrim){
  15. $len = strlen($toTrim);
  16. if($toTrim[0]=="(" && $toTrim[$len-1]==")"){
  17. if(isPossible($toTrim)) $toTrim = substr($toTrim, 1, -1);
  18. }
  19. return $toTrim;
  20. }
  21.  
  22. class TreeCalc {
  23. public $left;
  24. public $right;
  25. private $value;
  26. private $leaf;
  27.  
  28. public function __construct(){
  29. $this->left = null;
  30. $this->right = null;
  31. $this->value = null;
  32. $this->leaf = false;
  33. }
  34.  
  35. public function isLeaf(){
  36. return $this->leaf;
  37. }
  38.  
  39. public function getValue(){
  40. return $this->value;
  41. }
  42.  
  43. private function tokenize($inputString){
  44. $pars = 0;
  45. $weight = -1;
  46. $tok = -1;
  47. $op = "";
  48. for($i=0; $i<strlen($inputString); $i++){
  49. switch($inputString[$i]){
  50. case "(" :
  51. $pars++;
  52. break;
  53. case ")" :
  54. $pars--;
  55. break;
  56. case "+":
  57. if($pars>0) break;
  58. if($weight < 10){
  59. $tok = $i;
  60. $op = "+";
  61. $weight = 10;
  62. }
  63. break;
  64. case "-":
  65. if($pars>0) break;
  66. if($weight < 10){
  67. $tok = $i;
  68. $op = "-";
  69. $weight = 10;
  70. }
  71. break;
  72. case "*":
  73. if($pars>0) break;
  74. if($weight < 5){
  75. $tok = $i;
  76. $op = "*";
  77. $weight = 5;
  78. }
  79. break;
  80. case "/":
  81. if($pars>0) break;
  82. if($weight < 5){
  83. $tok = $i;
  84. $op = "/";
  85. $weight = 5;
  86. }
  87. break;
  88. case "^":
  89. if($pars>0) break;
  90. if($weight < 1){
  91. $tok = $i;
  92. $op = "^";
  93. $weight = 1;
  94. }
  95. break;
  96. }
  97. }
  98. if($weight==-1){
  99. $this->leaf = true;
  100. $this->value = $inputString;
  101. return;
  102. }
  103. $this->value=$op;
  104. $leftString = substr($inputString, 0, $tok);
  105. $leftString = trim($leftString);
  106. $leftString = trimpars($leftString);
  107.  
  108. $rightString = substr($inputString, $tok+1);
  109. $rightString = trim($rightString);
  110. $rightString = trimpars($rightString);
  111.  
  112. $this->left = new TreeCalc();
  113. $this->left->tokenize($leftString);
  114. $this->right = new TreeCalc();
  115. $this->right->tokenize($rightString);
  116. }
  117.  
  118. public function debugPrint(){
  119. echo $this->value;
  120. if($this->left != null) $this->left->debugPrint();
  121. if($this->right != null) $this->right->debugPrint();
  122. }
  123.  
  124. private function compute(){
  125. if($this->isLeaf()) return;
  126. if($this->left->isLeaf()==false){
  127. $this->left->compute();
  128. }
  129. if($this->right->isLeaf()==false){
  130. $this->right->compute();
  131. }
  132. switch($this->value){
  133. case "+":
  134. $this->value = $this->left->getValue() + $this->right->getvalue();
  135. break;
  136. case "-":
  137. $this->value = $this->left->getValue() - $this->right->getValue();
  138. break;
  139. case "*":
  140. $this->value = $this->left->getValue() * $this->right->getValue();
  141. break;
  142. case "/":
  143. $this->value = $this->left->getValue() / $this->right->getValue();
  144. break;
  145. case "^":
  146. $this->value = pow($this->left->getValue(), $this->right->getValue());
  147. break;
  148. }
  149. $this->leaf = true;
  150. $this->left = null;
  151. $this->right = null;
  152. }
  153.  
  154. public function calculate($toCalc){
  155. $this->tokenize($toCalc);
  156. $this->compute();
  157. return $this->getValue();
  158. }
  159. }
  160.  
  161.  
  162. $test = new TreeCalc();
  163. echo $test->calculate("3*2^(2+3)+((2+2)*2)-1");
Success #stdin #stdout 0s 82880KB
stdin
Standard input is empty
stdout
103