Ruby 如何减少if语句?
通过Chris Pine的学习编程和数字到罗马数字转换项目。下面的代码可以工作,但是它非常难看,包含所有的if(和end)语句。但是,当我使用elsif时,如果程序没有响应(似乎冻结)。任何想法都会有帮助Ruby 如何减少if语句?,ruby,Ruby,通过Chris Pine的学习编程和数字到罗马数字转换项目。下面的代码可以工作,但是它非常难看,包含所有的if(和end)语句。但是,当我使用elsif时,如果程序没有响应(似乎冻结)。任何想法都会有帮助 def calc input roman_numeral = '' while true if input >= 1000 roman_numeral += 'M' * (input / 1000) input = input - (1000 * (input / 1000
def calc input
roman_numeral = ''
while true
if input >= 1000
roman_numeral += 'M' * (input / 1000)
input = input - (1000 * (input / 1000))
if input <= 999 || input >= 500
roman_numeral += 'D' * (input / 500)
input = input - (500 * (input / 500))
if input <= 499 || input >= 100
roman_numeral += 'C' * (input / 100)
input = input - (100 * (input / 100))
if input <= 99 || input >= 50
roman_numeral += 'L' * (input / 50)
input = input - (50 * (input / 50))
if input <= 49 || input >= 10
roman_numeral += 'X' * (input / 10)
input = input - (10 * (input / 10))
if input <= 9 || input >= 5
roman_numeral += 'V' * (input / 5)
input = input - (5 * (input / 5))
if input <= 4 || input >= 1
roman_numeral += 'I' * (input / 1)
input = input - (1 * (input / 1))
puts roman_numeral
break
end
end
end
end
end
end
end
end
end
puts 'Give me a number, any number:'
input = gets.chomp.to_i
calc(input)
def计算输入
罗马数字=“”
虽然是真的
如果输入>=1000
罗马数字+='M'*(输入/1000)
输入=输入-(1000*(输入/1000))
如果输入=500
罗马数字+='D'*(输入/500)
输入=输入-(500*(输入/500))
如果输入=100
罗马数字+='C'*(输入/100)
输入=输入-(100*(输入/100))
如果输入=50
罗马数字+='L'*(输入/50)
输入=输入-(50*(输入/50))
如果输入=10
罗马数字+='X'*(输入/10)
输入=输入-(10*(输入/10))
如果输入=5
罗马数字+='V'*(输入/5)
输入=输入-(5*(输入/5))
如果输入=1
罗马数字+='I'*(输入/1)
输入=输入-(1*(输入/1))
放罗马数字
打破
结束
结束
结束
结束
结束
结束
结束
结束
结束
写“给我一个号码,任何号码:”
输入=gets.chomp.to_i
计算(输入)
将该方法与数组一起使用很方便:
ARR = [[1000,'M'], [ 500,'D'], [100,'C'], [50,'L'], [10,'X'], [5,'V'], [1,'I']]
def which(input)
ARR.find { |v,_| input >= v }
end
which(2) #=> [1, "I"]
which(7) #=> [5, "V"]
which(17) #=> [10, "X"]
which(77) #=> [50, "L"]
which(777) #=> [500, "D"]
which(7777) #=> [1000, "M"]
假设将整数转换成罗马数字,请考虑使用该方法。假设整数是2954
,并且您已经确定有两个“M”和一个“D”
(因此您的罗马数字字符串的开头是“MMD”
),并且454
是剩余的。然后:
c, rem = 454.divmod(100)
#=>[4, 54]
c #=> 4
rem #=> 54
告诉您还有四个“C”
,剩余54
但是,四个“C”
“CD”
(不是“CCCC”
),因此您可能需要使用如下哈希:
REP = {..., "C"=>["C", "CC", "CCC", "CD"], ...}
将
“C”
的数字转换为罗马数字。在这里,您可以将REP[“C”][4-1]#=>“CD”
附加到“MMD”
:“MMD”MMDCD“
,将该方法与数组一起使用很方便:
ARR = [[1000,'M'], [ 500,'D'], [100,'C'], [50,'L'], [10,'X'], [5,'V'], [1,'I']]
def which(input)
ARR.find { |v,_| input >= v }
end
which(2) #=> [1, "I"]
which(7) #=> [5, "V"]
which(17) #=> [10, "X"]
which(77) #=> [50, "L"]
which(777) #=> [500, "D"]
which(7777) #=> [1000, "M"]
假设将整数转换成罗马数字,请考虑使用该方法。假设整数是2954
,并且您已经确定有两个“M”和一个“D”
(因此您的罗马数字字符串的开头是“MMD”
),并且454
是剩余的。然后:
c, rem = 454.divmod(100)
#=>[4, 54]
c #=> 4
rem #=> 54
告诉您还有四个“C”
,剩余54
但是,四个“C”
“CD”
(不是“CCCC”
),因此您可能需要使用如下哈希:
REP = {..., "C"=>["C", "CC", "CCC", "CD"], ...}
将
“C”
的数字转换为罗马数字。在这里,您可以将REP[“C”][4-1]#=>“CD”
附加到“MMD”
:“MMD”“MMDCD”
Cary Swoveland的答案是减少if
块嵌套的一个极好的方法
他的答案告诉你下一个数字是哪个,但不是多少(就像你的代码中那样)。将其连接在一起的自然方法是使用递归函数调用:
class Romans
def self.calc(input, acc = "")
raise ArgumentError.new("Roman Numerals must be positve") if input < 0
raise ArgumentError.new("Roman Numerals must be integers") if ! input.is_a? Integer
return acc if input == 0
amount, numeral = which(input)
acc += numeral
input -= amount
calc(input, acc)
end
@@ARR = [[1000,'M'], [ 500,'D'], [100,'C'], [50,'L'], [10,'X'], [5,'V'], [1,'I']]
def self.which(input)
@@ARR.find { |v,_| input >= v }
end
end
请注意,ruby没有TCO,因此会用足够大的数字破坏堆栈-但是如果您需要800万的罗马数字版本,您可能需要编写一些新的字母。Cary Swoveland的答案是减少
if
块嵌套的一个很好的方法
他的答案告诉你下一个数字是哪个,但不是多少(就像你的代码中那样)。将其连接在一起的自然方法是使用递归函数调用:
class Romans
def self.calc(input, acc = "")
raise ArgumentError.new("Roman Numerals must be positve") if input < 0
raise ArgumentError.new("Roman Numerals must be integers") if ! input.is_a? Integer
return acc if input == 0
amount, numeral = which(input)
acc += numeral
input -= amount
calc(input, acc)
end
@@ARR = [[1000,'M'], [ 500,'D'], [100,'C'], [50,'L'], [10,'X'], [5,'V'], [1,'I']]
def self.which(input)
@@ARR.find { |v,_| input >= v }
end
end
请注意,ruby没有TCO,因此会用足够大的数字破坏堆栈-但是如果您需要800万的罗马数字版本,您可能需要编写一些新字母。这里有一个使用字符串乘法的字母。例如:('M'*3)='MMM'
def到_-roman(数字)
raise“必须使用正数。”如果数字这里有一个使用字符串乘法的。例如:('M'*3)='MMM'
def到_-roman(数字)
raise“必须使用正数”。如果数字为case输入;当1..4罗马数字+='I'*(输入/1);。。。当5..9罗马数字+='V'*(输入/5);。。。案例输入;当1..4罗马数字+='I'*(输入/1);。。。当5..9罗马数字+='V'*(输入/5);。。。卡里-感谢您快速而详细的回复。从高层次上讲,这是有道理的,但我认为,在我能够正确实施您建议的方法之前,我还有一段路要走。当我有你的时候:对于新手红宝石爱好者的资源有什么建议吗?正如我在文章中提到的,我现在正在学习Practical的初学者编程,我很喜欢。如果您有任何其他建议,我们将不胜感激。以下是一些可能性:,以及.Cary上列出的建议-感谢您的快速详细回复。从高层次上讲,这是有道理的,但我认为,在我能够正确实施您建议的方法之前,我还有一段路要走。当我有你的时候:对于新手红宝石爱好者的资源有什么建议吗?正如我在文章中提到的,我现在正在学习Practical的初学者编程,我很喜欢。任何其他建议都将不胜感激。以下是一些可能性:,以及在.Chris上列出的可能性。谢谢您的回复。正如w/Cary的回答,这在高水平上是有意义的,但是我认为在我能够利用你的方法之前,我还有一点要做。这里没有人。不管怎样,谢谢你!克里斯-谢谢你的回复。正如w/Cary的回答,这在高水平上是有意义的,但是我认为在我能够利用你的方法之前,我还有一点要做。这里没有人。不管怎样,谢谢你!