Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 如何减少if语句?_Ruby - Fatal编程技术网

Ruby 如何减少if语句?

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

通过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))

  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的回答,这在高水平上是有意义的,但是我认为在我能够利用你的方法之前,我还有一点要做。这里没有人。不管怎样,谢谢你!