【问题标题】:Ruby Code Explanation: Numbers to String using RecursionRuby 代码说明:使用递归将数字转换为字符串
【发布时间】:2017-01-16 10:11:10
【问题描述】:

有人分享了一些关于他们如何完成将数字转换为单词的挑战的 Ruby 代码。到目前为止,这个解决方案是最容易阅读的,但我并不完全理解它的递归方面。具体来说,在下面的行中......

elsif int.to_s.length == 1 && int/num > 0
  return str + "#{name}" 

如果 return 语句将代码从循环中中断,为什么这段代码不执行并在它为真时中断循环?例如,当 int = 4 且 num = 1 时,这将被证明为 true 并触发 return 语句,但代码会一直持续到 num = 4。

对代码的这方面的任何澄清,以及任何理解此解决方案的一般建议,都会有所帮助。仍在尝试理解递归。谢谢

def in_words(int)
  numbers_to_name = {
      1000000 => "million",
      1000 => "thousand",
      100 => "hundred",
      90 => "ninety",
      80 => "eighty",
      70 => "seventy",
      60 => "sixty",
      50 => "fifty",
      40 => "forty",
      30 => "thirty",
      20 => "twenty",
      19=>"nineteen",
      18=>"eighteen",
      17=>"seventeen", 
      16=>"sixteen",
      15=>"fifteen",
      14=>"fourteen",
      13=>"thirteen",              
      12=>"twelve",
      11 => "eleven",
      10 => "ten",
      9 => "nine",
      8 => "eight",
      7 => "seven",
      6 => "six",
      5 => "five",
      4 => "four",
      3 => "three",
      2 => "two",
      1 => "one"
    }

  str = ""
  numbers_to_name.each do |num, name|
    if int == 0
      return str
    elsif int.to_s.length == 1 && int/num > 0
      return str + "#{name}"      
    elsif int < 100 && int/num > 0
      return str + "#{name}" if int%num == 0
      return str + "#{name} " + in_words(int%num)
    elsif int/num > 0
      return str + in_words(int/num) + " #{name} " + in_words(int%num)
    end
  end
end

puts in_words(4) == "four"
puts in_words(27) == "twenty seven"
puts in_words(102) == "one hundred two"
puts in_words(38_079) == "thirty eight thousand seventy nine"
puts in_words(82102713) == "eighty two million one hundred two thousand seven hundred thirteen"

【问题讨论】:

    标签: ruby recursion


    【解决方案1】:

    调试代码

    这是一个修改后的版本,每个分支都有调试行:

    def in_words(int, indent="")
      puts "#{indent}in_words(#{int})"
      numbers_to_name = {
          1000000 => "million",
          1000 => "thousand",
          100 => "hundred",
          90 => "ninety",
          80 => "eighty",
          70 => "seventy",
          60 => "sixty",
          50 => "fifty",
          40 => "forty",
          30 => "thirty",
          20 => "twenty",
          19=>"nineteen",
          18=>"eighteen",
          17=>"seventeen", 
          16=>"sixteen",
          15=>"fifteen",
          14=>"fourteen",
          13=>"thirteen",              
          12=>"twelve",
          11 => "eleven",
          10 => "ten",
          9 => "nine",
          8 => "eight",
          7 => "seven",
          6 => "six",
          5 => "five",
          4 => "four",
          3 => "three",
          2 => "two",
          1 => "one"
        }
    
      str = ""
      numbers_to_name.each do |num, name|
        puts "#{indent}  testing #{num}"
        if int == 0
          puts "#{indent}   Empty string"
          return str
        elsif int.to_s.length == 1 && int/num > 0
          puts "#{indent}  Single digit found (#{name})!"
          return str + "#{name}"      
        elsif int < 100 && int/num > 0
          puts "#{indent}  Double digits found (#{name})!"
          return str + "#{name}" if int%num == 0
          puts "#{indent}  Recursive call with #{int%num} :"
          return str + "#{name} " + in_words(int%num, indent+"  ")
        elsif int/num > 0
          puts "#{indent}  Recursive call with #{int/num} and #{int%num} :"
          indent += "  "
          return str + in_words(int/num, indent) + " #{name} " + in_words(int%num,indent)
        end
      end
    end
    

    对于in_words(4),它输出:

    in_words(4)
      testing 1000000
      testing 1000
      testing 100
      testing 90
      testing 80
      testing 70
      testing 60
      testing 50
      testing 40
      testing 30
      testing 20
      testing 19
      testing 18
      testing 17
      testing 16
      testing 15
      testing 14
      testing 13
      testing 12
      testing 11
      testing 10
      testing 9
      testing 8
      testing 7
      testing 6
      testing 5
      testing 4
      Single digit found (four)!
    four
    

    27 岁:

    in_words(27)
      testing 1000000
      testing 1000
      testing 100
      testing 90
      testing 80
      testing 70
      testing 60
      testing 50
      testing 40
      testing 30
      testing 20
      Double digits found (twenty)!
      Recursive call with 7 :
      in_words(7)
        testing 1000000
        testing 1000
        testing 100
        testing 90
        testing 80
        testing 70
        testing 60
        testing 50
        testing 40
        testing 30
        testing 20
        testing 19
        testing 18
        testing 17
        testing 16
        testing 15
        testing 14
        testing 13
        testing 12
        testing 11
        testing 10
        testing 9
        testing 8
        testing 7
        Single digit found (seven)!
    twenty seven
    

    回答

    例如,当 int = 4 且 num = 1 时,这将被证明是正确的并且 触发 return 语句,但代码一直持续到 num = 4。

    使用4 作为输入,num = 1 将永远不会发生。 numbers_to_name 是按降序排列的,所以num=4 会发生return 语句,之后该方法不会执行任何其他代码。

    【讨论】:

    • 啊——谢谢!我现在意识到每个循环都是从顶部开始 - 数百万 - 向下。对我来说不好的忽视。谢谢你花时间给我看!!
    猜你喜欢
    • 2019-05-18
    • 2011-10-22
    • 1970-01-01
    • 1970-01-01
    • 2012-06-16
    • 1970-01-01
    • 2020-02-17
    • 2018-11-13
    相关资源
    最近更新 更多