2014-01-09 78 views
0

我想確保輸入的羅馬數字是有效的。我的策略是從第一個或第二個字符開始,如果字符串之後的任何內容都無效,那麼我告訴他們重新輸入他們的號碼。如果我這樣做,我需要爲D,CD,C,XC,L,XL,X,IX,V,IV和I.創造一個條件。我寫下這種條件語句的最佳方式是粘貼的方式,還是有更漂亮的方法?if語句的條件太多?

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

回答

3

嘗試下面使用Enumerable#any?

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?)) 
+0

謝謝!那個好漂亮。將在10分鐘內接受答案。 – user3138341

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. 
+1

這是非常令人印象深刻的。我甚至沒有完全理解你的代碼,sawa,但它在少量代碼中工作的事實非常酷。 – user3138341

0
(['M', 'D', 'C'] & string[2..-1].chars).any? 

有沒有必要檢查string[2..-1]'CD',如'CD'可以不存在,除非「C」和「D」也存在。相同的'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