我正在努力确保输入的罗马数字有效。我的策略是从前一个或两个字符开始,如果字符串中的任何内容无效,那么我告诉他们重新输入他们的号码。如果我这样做,我需要为下面的D,CD,C,XC,L,XL,X,IX,V,IV和I.制定一个条件。我粘贴的方式是编写此条件语句的最佳方式还是更漂亮的方式?
string = "CMCMD"
integer_num = 0
if string[0..1] = "CM"
if string[2..-1].include? "M" || string[2..-1].include? "CD" || string[2..-1].include? "D" || string[2..-1].include "CM" || string[2..-1].include? "C"
puts "This is invalid. Please enter your roman numeral correctly."
else
add 900 to integer_num and slice CM off the beginning of the string.
end
end
我查看了文档,以及关于S.O的一些事情,如this one。
答案 0 :(得分:3)
if ["M","CD","D","CM","C"].any?{|e| string[2..-1].include? e }
或
ary = %w(M CD D CM C)
if ary.any?(&string[2..-1].method(:include?))
答案 1 :(得分:1)
这是我个人图书馆的一种方法,可将罗马数字字符串转换为数字。您的问题不清楚您认为哪种字符串无效。我的方法试图从罗马字符中最大限度地理解。
class String
RomanToI = {"i"=>1, "v"=>5, "x"=>10, "l"=>50, "c"=>100, "d"=>500, "m"=>1000}
def roman_to_i!
prev = 1000
downcase.each_char.inject(0) do |i, d|
raise "Invalid string as Roman numeral" unless d = RomanToI[d]
(d <= prev) ? prev = d : i -= (prev * 2)
i += d
end
end
end
"mmxiv".roman_to_i! # => 2014
"a".roman_to_i! # => Invalid string as Roman numeral.
答案 2 :(得分:0)
(['M', 'D', 'C'] & string[2..-1].chars).any?
string[2..-1]
无法检查'CD'
,因为除非'C'和'D'也存在,否则'CD'
不能出现。与'CM'
相同。
string
的第一和第二部分确实应该是变量。也许做这样的事情:
cases = {'CM' => {suffix: 'CMD', illegal: ['M', 'D', 'C']},
'CD' => {...},
...}
def invalid?(str, illegal)
(str.chars & illegal).any?
end
def check_all(cases)
cases.each do |c, v|
if invalid?(v[:suffix], v[:illegal])
...
end
end
end