【问题标题】:String Based Calculator with units and rationals具有单位和有理数的基于字符串的计算器
【发布时间】:2014-06-30 14:09:23
【问题描述】:

给定一个字符串

7 1/3 inches - 4.12mm

将混合数(7 1/3)关联并建立以下顺序操作的最佳方法是什么

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

我的第一次尝试是用运算符 (+,-,*,/,%) 拆分字符串,但显然不符合理性要求。操作顺序是关键,但我不知道如何通过代码实现它。

【问题讨论】:

    标签: ruby string math calculator units-of-measurement


    【解决方案1】:

    我认为您确实需要使用定义语法来查看正确的解析器。类似于 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 { 结果 = val[0] + val1 } | exp '+' exp { 结果 = val[0] + val1 } | exp '-' exp { 结果 = val[0] - val1 } | exp '*' exp { 结果 = val[0] * val1 } | exp '/' exp { 结果 = val[0] / val1 }

    您需要添加优先规则和处理计量单位的规则。

    另一种方法是实现一个可以解析数学表达式的Shunting-yard algorithm

    【讨论】:

    • 所以我们最终编写了一个 gem 来处理特定用例,解析英制木材单位。它使用 RubyUnits 和 Citrus 来表示单元和语法。在这里查看github.com/burningpony/tape_measure
    • 我推荐的一件事是拥有一个测试框架。准备一堆已知公式和预期结果并使用ruby-doc.org/stdlib-1.8.7/libdoc/test/unit/rdoc/Test/Unit.html,这样可以确保您的解析器处理您能想到的尽可能多的情况。
    • 当然,我们坚持使用 rspec。至少对于我们的垂直领域来说,它已经被很好地覆盖了,我们必须处理相当多的不良数据,并且该 gem 在发布后大约 3 个月就已经投入生产。实际上,它为能处理的垃圾感到非常自豪。 github.com/burningpony/tape_measure/blob/master/spec/…
    【解决方案2】:

    为了在不丢失顺序的情况下将字符串拆分为多个部分,您可以执行以下操作:

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

    此代码在空格以及数字和字母之间的边界上分割。

    现在你要做的就是lex 数组,然后计算你的结果

    【讨论】:

      猜你喜欢
      • 2019-06-27
      • 2013-02-26
      • 1970-01-01
      • 2016-03-06
      • 2020-05-26
      • 2019-05-01
      • 2012-02-13
      • 1970-01-01
      相关资源
      最近更新 更多