Струнный калькулятор с единицами и рациональными числами
Учитывая строку
7 1/3 inches - 4.12mm
Как лучше всего связать смешанное число (7 1/3) и установить порядок операций ниже?
((7 1/3) inches) - (4.12 millimeters) = 7.17112861 inches
Моя первая попытка была разбить строку с помощью операторов (+,-,*,/,%), но явно не соответствует рациональному требованию. Порядок операций является ключевым, но я заблудился, как реализовать это с помощью кода.
2 ответа
Я думаю, что вам действительно нужно искать правильный синтаксический анализатор с использованием определенной грамматики. Что-то вроде решения lex / yacc. Я не очень знаком с ruby, но кажется, что есть некоторые реализации ruby
http://www.ruby-doc.org/stdlib-2.1.0/libdoc/racc/parser/rdoc/Racc.html http://i.loveruby.net/en/projects/racc/doc/
Вы можете рассматривать пространство как оператор, который действует как сложение. Помимо правил для стандартных математических операторов вы можете иметь
exp: exp '' exp {result = val [0] + val 1 } | exp '+' exp {result = val [0] + val 1 } | exp '-' exp {result = val [0] - val 1 } | exp '*' exp {result = val [0] * val 1 } | exp '/' exp {result = val [0] / val 1 }
Вам нужно будет добавить правила приоритета и правила для работы с единицами измерения.
Альтернативой этому может быть реализация алгоритма Shunting-yard, который может анализировать математические выражения.
Чтобы разбить строку на части без потери порядка, вы можете сделать следующее:
s = '7 1/3 inches - 4.12mm'
s.split(/(?: |(?:(?<=\d)(?=[a-z]))|(?:(?<=[a-z])(?=\d)))/)
# => ["7", "1/3", "inches", "-", "4.12", "mm"]
Этот код разделяется на пробелы и на границе между цифрами и буквами.
Теперь все, что вам нужно сделать, это добавить массив и вычислить ваш результат.