Оценка строки простых математических выражений [закрыто]


вызов

вот вызов (моего собственного изобретения, хотя я не удивлюсь, если он ранее появился в другом месте в интернете).

написать функцию, которая принимает один аргумент, который является строковое представление простого математическое выражение и вычисляет это как значение с плавающей запятой. Один "простое выражение" может включать следующее: положительный или отрицательный десятичные числа, +, -,*,/,(,). Выражения use (normal) инфиксной нотации. Операторы должны быть оценены в порядок их появления, т. е. не как в BODMAS, хотя скобки должны быть правильно наблюдал, конечно. Функция должна возвращать правильный результат для любой возможные выражения такой формы. Однако, функция не имеет к обрабатывать искаженные выражения (т. е. с плохим синтаксисом).

примеры выражений:

1 + 3 / -8                            = -0.5       (No BODMAS)
2*3*4*5+99                            = 219
4 * (9 - 4) / (2 * 6 - 2) + 8         = 10
1 + ((123 * 3 - 69) / 100)            = 4
2.45/8.5*9.27+(5*0.0023)              = 2.68...

правила

Я предвижу некоторую форму "обмана" / хитрости здесь, поэтому, пожалуйста, позвольте мне предостеречь от этого! Путем обмана, я имею в виду использование eval или эквивалентная функция в динамических языках, таких как JavaScript или PHP, или равно компиляция и выполнение кода на лету. (Я думаю, что моя спецификация "без БОДМ" в значительной степени гарантирована это однако.) Кроме того, нет никаких ограничений. Я ожидаю несколько регулярных выражений здесь, но было бы неплохо увидеть больше, чем просто это.

теперь меня в основном интересует решение C# / .NET здесь, но любой другой язык также был бы вполне приемлемым (в частности, F# и Python для функциональных/смешанных подходов). Я еще не решил, буду ли я принимать самое короткое или самое гениальное решение (по крайней мере, для языка) в качестве ответа, но я бы приветствовал любая форма решения на любом языке, кроме того, что я только что запретил выше!

Мое Решение

теперь я разместил свое решение C# здесь (403 символа). обновление: мое новое решение значительно превзошло старое в 294 символов, С помощью немного прекрасного регулярного выражения! Я подозревал, что это будет легко разбито некоторыми языками с более легким синтаксисом (особенно функциональными / динамическими), и были оказался прав, но мне было бы любопытно, если бы кто-то мог победить это в C# еще.

обновление

Я уже видел некоторые очень хитрые решения. Спасибо всем, кто разместил один. Хотя я еще не тестировал ни одного из них, я собираюсь доверять людям и предполагать, что они, по крайней мере, работают со всеми приведенными примерами.

только для Примечания, повторный вход (т. е. потокобезопасность) является не требование для функции, хотя это бонус.


30 76

30 ответов: