Question

Given a string

7 1/3 inches - 4.12mm

What would be the best method to associate the mixed number (7 1/3) and establish the order operations below

((7 1/3) inches) - (4.12 millimeters) = 7.17112861 inches

My first attempt was splitting the string with operators (+,-,*,/,%) but clearly does not meet the rational requirement. The order of operations is the key but I am lost on how to implement this via code.

Was it helpful?

Solution

I think you really need to be looking at a proper parser using a define grammar. Something like the lex/yacc solution. I'm not really conversant with ruby but it seems there are some ruby implementations

http://www.ruby-doc.org/stdlib-2.1.0/libdoc/racc/parser/rdoc/Racc.html http://i.loveruby.net/en/projects/racc/doc/

You can treat a space as an operator which functions like addition. On top of rules for the standard mathematical operators you might have

exp: exp ' ' exp { result = val[0] + val1 } | exp '+' exp { result = val[0] + val1 } | exp '-' exp { result = val[0] - val1 } | exp '*' exp { result = val[0] * val1 } | exp '/' exp { result = val[0] / val1 }

You will need to add precedence rules and rules for coping with the units of measurement.

An alternative to that would be to implement a Shunting-yard algorithm which can parse mathematical expressions.

OTHER TIPS

In order to split the string into its parts without losing the order you can do the following:

s = '7 1/3 inches - 4.12mm'

s.split(/(?: |(?:(?<=\d)(?=[a-z]))|(?:(?<=[a-z])(?=\d)))/)
# => ["7", "1/3", "inches", "-", "4.12", "mm"] 

This code splits on spaces and on the border between numbers and letters.

Now all you have to do is lex the array, and compute your result

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top