2017-03-12 93 views
2

我完成了具有以下指令的任務:跳過下一元音和輔音在一個字符串

僞代碼,寫,需要一個間諜的真實姓名(例如,「費利西亞託雷斯」)的方法,並創建一個通過執行以下操作僞造名稱:

交換姓氏和名字。 將'aeiou'中的所有元音(a,e,i,o或u)更改爲下一個元音,並將所有輔音(除元音之外的所有其他元音)更改爲字母表中的下一個輔音。

我的解決辦法:

@vowels = %w(a e i o u) 
@consonants = ("a".."z").to_a - @vowels 

def next_vowel(letter) 
    i = 0 
    while i < @vowels.length 
    if @vowels[i] == "u" 
     return @vowels[0] 
    elsif @vowels[i] == letter 
     return @vowels[i+1] 
    end 
    i += 1 
    end 
end 


def next_consonant(letter) 
    i = 0 
    while i < (@consonants.length) 
    if @consonants[i] == "z" 
     return @consonants[0] 
    elsif @consonants[i] == letter 
     return @consonants[i + 1] 
    end 
    i += 1 
    end 
end 


def alias_manager(name) 
    name.downcase! 
    first_name = name.split(" ")[0] 
    last_name = name.split(" ")[1] 


    alias_first_name = last_name.chars.map do |i| 
     if @vowels.include?(i) 
      next_vowel(i) 
     elsif @consonants.include?(i) 
      next_consonant(i) 
     end 
    end 


    alias_last_name = first_name.chars.map do |i| 
     if @vowels.include?(i) 
      next_vowel(i) 
     elsif @consonants.include?(i) 
      next_consonant(i) 
     end 
    end 
    alias_first_name.join.capitalize! + " " + alias_last_name.join.capitalize! 
end 

我試圖想到寫這個的一個更簡潔的方式。 'while'循環似乎不是最有效的方法。我正在考慮使用「旋轉」,但不知道如何替換字符串中的字母。另外,有沒有一種方法來重構first_namelast_name的最後迭代?我基本上爲不同的變量寫了兩次相同的東西。

回答

2

一種更好的方式來定義next_vowelnext_consonant

@vowels = %w(a e i o u) 
    @consonants = ("a".."z").to_a - @vowels 

    def next_vowel(letter) 
     i = @vowels.index(letter) 

     # Return the next vowel, using modulo for the last case (next of `u` is `a`) 
     @vowels[(i + 1) % @vowels.length] 

    end 

    def next_consonant(letter) 
     i = @consonants.index(letter) 

     # Return the next vowel, using modulo for the last case (next of `z` is `b`) 
     @consonants[(i + 1) % @consonants.length] 

    end 

一些測試用例:

2.3.3 :019 > next_vowel("a") 
=> "e" 
2.3.3 :020 > next_vowel("e") 
=> "i" 
2.3.3 :021 > next_vowel("u") 
=> "a" 
2.3.3 :022 > next_consonant("t") 
=> "v" 
2.3.3 :023 > next_consonant("z") 
=> "b" 
2.3.3 :024 > next_consonant("d") 
=> "f" 
1

這聽起來像你的問題可能是更適合https://codereview.stackexchange.com/

儘管如此 - 我建議你看看這兩種方法:

這樣可以簡化代碼是這樣的:

@vowels = %w(a e i o u) 
@consonants = ('a'..'z').to_a - @vowels 

def alias_manager(name) 
    rotate_letters(name).split.reverse.map(&:capitalize).join(' ') 
end 

def rotate_letters(name) 
    name.downcase.tr(@vowels.join, @vowels.rotate.join).tr(@consonants.join, @consonants.rotate.join) 
end 
+0

'tr(@ vowels.join,@ vowels.rotate.join)'是個好主意。 – mudasobwa

+0

這是迄今爲止最好的答案。 – mudasobwa

1

FWIW:

VOWELS = %w(a e i o u) | %w(a e i o u).map(&:upcase) 
CONSONANTS = ((?a..?z).to_a | (?a..?z).map(&:upcase)) - VOWELS 

def next_elem letter 
    array = VOWELS.include?(letter) ? VOWELS : CONSONANTS 
    array.each_cons(2) { |me, they| break they if me == letter } 
end 

"Felicia Torres".split(' ').reverse.map do |l| 
    l.split('').map(&method(:next_elem)) 
end.map(&:join).join(' ') 
#⇒ "Vussit Gimodoe" 
0

此方法的設計考慮到效率。這個想法是首先創建一個散列,它在加密單個單詞時使用字母映射(使用採用散列進行替換的String#gsub的形式)。這應該使加密速度非常快,這在加密很多字符串時特別有效。如下所述,使用散列的另一個好處是它可以輕鬆創建解密加密字符串的方法。

代碼

def create_hash(arr) 
puts "arr=#{arr}" 
    (arr + [arr.first]).each_cons(2).with_object({}) { |(k,v),h| h[k]=v } 
end 

v = %w(a e i o u) 
c = ("a".."z").to_a - v 
subs_hash = create_hash(v). 
      merge(create_hash(v.map(&:upcase))). 
      merge(create_hash(c)). 
      merge(create_hash(c.map(&:upcase))) 
    #=> {"a"=>"e", "e"=>"i", "i"=>"o", "o"=>"u", "u"=>"a", 
    # "A"=>"E", "E"=>"I", "I"=>"O", "O"=>"U", "U"=>"A", 
    # "b"=>"c", "c"=>"d", ..., "y"=>"z", "z"=>"b", 
    # "B"=>"C", "C"=>"D", ..., "Y"=>"Z", "Z"=>"B"} 

def code(str, subs_hash) 
    str.split.reverse.map { |word| word.gsub(/./, subs_hash) }.join(' ') 
end 

實例

code("Felicia Torres", h) 
    #=> "Vussit Gimodoe" 
code("eenie meanie", h) 
    #=> "niepoi iipoi" 

解密加密的字符串使用散列的

一個優點是,它使得編寫一個decode方法非常容易。

inverted_subs_hash = subs_hash.invert 
    #=> {"e"=>"a", "i"=>"e", "o"=>"i", "u"=>"o", "a"=>"u", 
    # "E"=>"A", "I"=>"E", "O"=>"I", "U"=>"O", "A"=>"U", 
    # "c"=>"b", "d"=>"c",..., "z"=>"y", "b"=>"z", 
    # "C"=>"B", "D"=>"C",..., "Z"=>"Y", "B"=>"Z"} 

def decode(str, inverted_subs_hash) 
    code(str, inverted_subs_hash) 
end 

decode "Vussit Gimodoe", inverted_subs_hash 
    #=> "Felicia Torres" 

大寫和小寫

如果該字符串第一downcased,刪除

merge(create_hash(v.map(&:upcase))). 

merge(create_hash(c.map(&:upcase))) 

這樣做在decode(code(str)) != str結果,除非我們假設第一每個單詞的字母大寫d所有其他字符都是小寫字母,在這種情況下,我們可以通過對每個解碼字應用(作爲最後一步)String#capitalize來使decode返回原始字符串。

相關問題