因此,在寻找能够获取整数并返回该整数的字符串值的方法时,我找到了这个解决方案:
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
这个答案很棒,因为它为我提供了一个关于我想要做什么的答案。但是,我很新,并不完全明白它是如何工作的。我确实理解哈希,但我不明白作者如何在哈希下面构造他的代码。我试图减少这些代码并逐行测试,但是当我这样做时它不起作用。我只想弄清楚他们为什么/如何执行int/num
之类的事情,并在他们的块代码中间使用他们的方法in_words
。
如果有人有时间一步一步地解决这个问题,并解释这段代码是如何运作的,我将非常感激。注意:我会对原始作者的解决方案做出评论,但我不被允许,因为我没有足够的“声誉”这样做。
答案 0 :(得分:3)
# Loop through the hash, `num` is the hash key, `name` is the hash value
numbers_to_name.each do |num, name|
# Zero is not used in the lookup table, so return an empty string if that
# was an argument supplied to the function (e.g., in_words(0) )
if int == 0
return str
# If it's a single digit number (e.g., `6`) and is equal to the key (e.g., 6/6 == 1)
# then return the word/name
elsif int.to_s.length == 1 && int/num > 0
return str + "#{name}"
# If your supplied number was less than a hundred (e.g., `50`)
elsif int < 100 && int/num > 0
return str + "#{name}" if int%num == 0
# If your supplied number was something like `57` you would return `fifty` and
# then need to convert the `7` to `seven`, so call the function
# again ( 57%50 has a remainder of 7, so in_words(7) translate the 7)
return str + "#{name} " + in_words(int%num)
# For instance, 567 => five hundred sixty seven:
elsif int/num > 0
return str + in_words(int/num) + " #{name} " + in_words(int%num)
end
end
这里有一个递归问题,这就是为什么你看到in_words
在多个地方被调用的原因。
我认为一个重要的注意事项是导入哈希键的方式(从最大到最小)。在Ruby 1.9+中,枚举哈希键以便保持它们的顺序。鉴于代码的逻辑,每次循环时,它都会接受产生正结果的第一个键。
举一个例子,有很多地方使用int/num > 0
。如果你的数字是6,那么它将首先针对1000000进行测试。6/1000000
将导致0
,因为分子和分母都是整数。使用整数很重要,因为6/1000000.0
会导致浮点数并且大于0(并且if语句将为true - bad)。这意味着它将继续迭代键(从最大的输入顺序到最小的输入顺序),并且它到达匹配的第一个将是你想要的那个。
举一个以相反顺序(从最小到最大)排序的哈希的例子,想象你想把5翻译成一个单词。 5.to_s.length == 1
是真的,但那时int/num > 0
。在这种情况下,int
为5
,您的第一个密钥为1
; 5 / 1
大于零,因此评估为true并返回散列one
中的值。换句话说,in_words(5)
会返回one
,这是不正确的。在代码中找到的哈希顺序(从最大到最小)将迭代所有键5/10000000 ... 5/6
,它们都等于0,但随后到达第一个大于零的分区(5 / 5 == 1
)并且具有所需的价值。
答案 1 :(得分:0)
肯定有更快/更清晰的方法来实现这一点,并且递归完全被误导但是......
#loop thru all the items in the hash and assign the hey to num and val to name
numbers_to_name.each do |num, name|
# if the input parameter is zero return str which is ""
if int == 0
return str
# if the length of the string representation of the input parameter is 1 and an empty string divided by the current key is larger than 0 return str + name (this is insane)
elsif int.to_s.length == 1 && int/num > 0
return str + "#{name}"
# if the key value is less than 100 and an empty string divided by the current key is larger than 0 return str + name if the modulus of key and num is 0, if not? return "" + in_words(int%num) (this is also insane)
elsif int < 100 && int/num > 0
return str + "#{name}" if int%num == 0
return str + "#{name} " + in_words(int%num)
# if the input parameter divided by the key is larger than 0 return "" + the result of this function with the key/num as input + the current items value + in_words(int%num)
elsif int/num > 0
return str + in_words(int/num) + " #{name} " + in_words(int%num)
end
end
我的眼睛现在正在流血,但这正是发生的事情。