我想写一个简单的计算器

时间:2015-12-02 14:14:31

标签: ruby

我正在尝试编写一个将字符串作为输入的计算器,例如"2+4-7/2",并计算它。它应该处理操作的顺序。

string = '1+1'
module Simple_calculator
  class << self
    def calculate(string)
      operators = [:+, :-, :*, :/]
      res = string
      operators.each do |op|
        splits = string.split(op.to_s)
        if splits.size > 1
          resMap = splits.map do |sp|
            calculate(sp)
          end
          resMap.map(&:to_f).inject(op)
        end
      end
      res.to_f
    end
  end
end

我的代码中出错了什么?

2 个答案:

答案 0 :(得分:1)

  

我的代码中出错了什么?

您可以通过运算符拆分字符串,例如:

"1+2+3".split("+")
#=> ["1", "2", "3"]

这看起来是错误的做法。加法,减法,乘法和除法是二进制操作,即它们组合两个元素(操作数),而不是 n 元素。

在您的代码中,1 + 2 + 3被视为:

  +
 /|\
1 2 3

这使得组合(不同操作的结果)变得更加困难。

更容易对待1 + 2 + 3,如:

  +              +
 / \            / \ 
1   +    or    +   3
   / \        / \
  2   3      1   2

显然,这可以使用递归来解决。这是一个非常基本的解析器/计算器:

def parse(string)
  case string
  when /(.*)\+(.*)/ then parse($1) + parse($2)
  when /(.*)\*(.*)/ then parse($1) * parse($2)
  when /^(\d+)$/    then $1.to_i
  else
    raise SyntaxError
  end
end

规则很简单:

  1. /(.*)\+(.*)/匹配a+b并返回parse(a) + parse(b)
  2. /(.*)\*(.*)/匹配a*b并返回parse(a) * parse(b)
  3. /^(\d+)$/匹配或更多数字并返回相应的整数
  4. 其他任何内容都会产生SyntaxError
  5. 请注意,ab可以是任何内容,而不仅仅是数字。

    实施例

    数字变成数字(第3和第34条;规则&#34;):

    parse("1")
    #=> "1".to_i
    #=> 1
    
    parse("123")
    #=> "123".to_i
    #=> 123
    

    a+b评估为parse(a) + parse(b)

    parse("3+4")
    #=> parse("3") + parse("4")
    #=>   "3".to_i + "4".to_i
    #=>          3 + 4
    #=>            7
    

    a+b*c评估为:

    parse("1+2*3")
    #=> parse("1") + parse("2*3")
    #=>   "1".to_i + parse("2*3")
    #=>          1 + parse("2*3")
    #=>          1 + parse("2") * parse("3")
    #=>          1 +   "2".to_i * parse("3")
    #=>          1 +          2 * parse("3")
    #=>          1 +          2 * "3".to_i
    #=>          1 +          2 * 3
    #=>          1 +            6
    #=>            7
    

    操作顺序取决于匹配顺序。 a+b之前的a*b匹配,因此:

    parse("2*3+1")
    #=>            parse("2*3") + parse("1")
    #=>            parse("2*3") + parse("1")
    #=>            parse("2*3") + parse("1")
    #=> parse("2") * parse("3") + parse("1")
    #=>   "2".to_i * parse("3") + parse("1")
    #=>          2 * parse("3") + parse("1")
    #=>          2 * "3".to_i   + parse("1")
    #=>          2 * 3          + parse("1")
    #=>            6            + parse("1")
    #=>            6            + "1".to_i
    #=>            6            + 1
    #=>                         7
    

答案 1 :(得分:0)

嘿,你输入的是输入而不是结果。这是您的计算方法的快速修复。它的工作但仍然需要重建,因为你可以解析字符串以先找到运算符然后使用它而不是尝试计算所有运算符。

def calculate(string)
  operators = [:+, :-, :*, :/]
  operators.map do |op|
    splits = string.split(op.to_s)
    splits.map(&:to_f).inject(op) if splits.size > 1
  end.compact.first
end

快乐的编码!