跳到下一个元音和弦中的辅音

时间:2017-03-12 16:07:45

标签: arrays ruby string while-loop rotation

我完成了一项具有以下说明的作业:

  

伪代码并编写一个方法,该方法采用间谍的真实姓名(例如," Felicia Torres")并通过执行以下操作创建假名称:

     

交换名字和姓氏。   将所有元音(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

我试图想出一种更为简洁的写作方式。 &#39; while&#39;循环看起来不是最有效的方法。我正在考虑使用&#39; rotate&#39;但不知道如何替换字符串中的字母。另外,有没有办法重构first_namelast_name的最后一次迭代?我基本上为不同的变量写了两次相同的东西。

4 个答案:

答案 0 :(得分: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 :(得分:1)

听起来您的问题可能更适合https://codereview.stackexchange.com/

说 - 我建议你研究这两种方法:

这可以简化代码:

let hideEmptyViews = (list.count != 0)
emptyLabel.isHidden = hideEmptyViews
emptyLabel2.isHidden = hideEmptyViews
emptyImage.isHidden = hideEmptyViews

答案 2 :(得分: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"

答案 3 :(得分: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"

大写和小写

如果该字符串是第一个下载的,请删除

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

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

这样做会产生decode(code(str)) != str,除非我们假设每个单词的第一个字母都是大写的而所有其他字符都是小写的,在这种情况下我们可以通过应用{as}使decode返回原始字符串最后一步)String#capitalize到每个解码的单词。