Струнный калькулятор с единицами и рациональными числами

Учитывая строку

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"] 

Этот код разделяется на пробелы и на границе между цифрами и буквами.

Теперь все, что вам нужно сделать, это добавить массив и вычислить ваш результат.

Другие вопросы по тегам