fork download
  1. <?php
  2.  
  3. $string = "-2.43+3.62/2.1*9.02";
  4.  
  5. function calculate($string)
  6. {
  7. $reg = '/(\-*\d+([.,]\d+)*)|(\*)|(\/)|(\+)|(\-)/';
  8.  
  9. //Разбиваем выражение на данные и операторы
  10. if (preg_match_all($reg, $string, $matches)) {
  11. foreach($matches[0] as $position => $value) {
  12.  
  13. //Определяем приоритет действий
  14. switch($value) {
  15. case '*':
  16. $steps[1][$position] = $value;
  17. break;
  18. case '/':
  19. $steps[1][$position] = $value;
  20. break;
  21. case '+':
  22. $steps[2][$position] = $value;
  23. break;
  24. case '-':
  25. $steps[2][$position] = $value;
  26. break;
  27. }
  28. }
  29.  
  30. ksort($steps);
  31.  
  32.  
  33. //Считаем первое действие...
  34. foreach($steps as $step) {
  35. foreach($step as $position => $operator) {
  36. switch($operator) {
  37. case '*':
  38. $exp = $matches[0][$position - 1] * $matches[0][$position +1];
  39. break;
  40. case '/':
  41. $exp = $matches[0][$position - 1] / $matches[0][$position +1];
  42. break;
  43. case '+':
  44. $exp = $matches[0][$position - 1] + $matches[0][$position +1];
  45. break;
  46. case '-':
  47. $exp = $matches[0][$position - 1] - $matches[0][$position +1];
  48. break;
  49. }
  50.  
  51.  
  52. //Получаем новое выражение с новыми данными
  53. $newMatches = [];
  54.  
  55. foreach($matches[0] as $key => $value) {
  56. if($key == $position - 1 or $key == $position or $key == $position + 1) {
  57. if ($key == $position) {
  58. $newMatches[] = $exp;
  59. }
  60.  
  61. continue;
  62. }
  63.  
  64. $newMatches[] = $value;
  65. }
  66.  
  67. $newString = '';
  68.  
  69. foreach($newMatches as $value) {
  70. $newString .= $value;
  71. }
  72.  
  73. //Рекурсивно повторяем вычисление до тех пор пока не получим единственное значение т.е. ответ
  74. if (count($newMatches) != 1) {
  75. return calculate($newString);
  76. } else {
  77. return $newMatches[0];
  78. }
  79.  
  80. break;
  81. }
  82. }
  83. }
  84. }
  85.  
  86. var_dump(calculate($string));
Success #stdin #stdout 0s 52488KB
stdin
Standard input is empty
stdout
float(13.118761904762)