用字母

时间:2016-04-21 18:29:49

标签: ruby string

我必须将字母表中的每个字母替换为字母表后面的字母(即c变为dz变为a),将每个元音大写(aeiou),并返回修改后的字符串。我试图在不调用sortfind等任何功能的情况下找到解决方案。

我有这个:

def LetterChanges(str)
  Changed_Letter = ""
  alphabet = [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z]
  for i in 0..str.length do 
    if str[i] == 
    str[i] = alphabet[i] + 1 
  return str 
end

但我迷路了。任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:2)

你被要求"映射"字母表中的每个字母都是另一个字母,因此您需要使用方法Enumerable#map

VOWELS = "aeiou"
letters = ('a'..'z').to_a
  #=> ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
       "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]                    
letters.map do |c|
  <code referencing c>
end
  #=> ['b', 'c', 'd', 'E', 'f',..., 'z', 'A]

现在让我们使用以下方法填写代码:

  • String#succ,给定一个字符,返回具有下一个更高ASCII值的字符。例如,"b".ord #=> 98"b".succ #=> "c",因为"c".ord #=> 99。自"z".succ #=> 'aa'起,我们需要对待&#34; z&#34;作为一个特例。 String#succString#next相同。
  • String#include?,给定一个字符串,返回truefalse,具体取决于include?的参数(字符串)是否包含在接收者中。例如,"cat".include?("at") #=> true; "cat".include?("a") #=> true; "cat".include?("z") #=> false。请注意,VOWELS,因为它以大写字母开头,是一个常量。
  • String#upcase,它将给定字符串中的所有小写字母转换为大写字母(并保留所有其他字符不变)。

letters.map do |c|
  if c == 'z'
    'A'
  else
    s = c.succ
    if VOWELS.include?(s)
      s.upcase
    else
      s
    end
  end
end
  #=> ["b", "c", "d", "E", "f", "g", "h", "I", "j", "k", "l", "m", "n",
  #    "O", "p", "q", "r", "s", "t", "U", "v", "w", "x", "y", "z", "A"]

你可以使用case语句和Ruby的ternary operator来写这个:

letters.map do |c|
  case c
  when 'z'
    'A'
  else
    s = c.succ
    VOWELS.include?(s) ? s.upcase : s
  end
end

或者您可以使用方法String#ordInteger#chr

letters.map do |c|
  s = ('a'.ord + ((c.ord-'a'.ord+1) % 26)).chr
  VOWELS.include?(s) ? s.upcase : s
  end
end

例如,如果c = 'r'

('a'.ord + ((c.ord-'a'.ord+1) % 26).chr
#=> (97 + ((114-97+1) % 26).chr
#=> (97 + 18 % 26).chr
#=> (97 + 18).chr
#=> 115.chr
#=> 's'

但是,c = 'z'

('a'.ord + ((c.ord-'a'.ord+1) % 26).chr
#=> (97 + ((122-97+1) % 26).chr
#=> (97 + 26 % 26).chr
#=> (97 + 0).chr
#=> 97.chr
#=> 'a'

还有一种方法。 (你可以弄清楚为什么会有效。)

letters.map do |c|
  s = c.succ[0]
  VOWELS.include?(s) ? s.upcase : s
end

您可能希望创建一个哈希值。

letter_mapping = {}
letters.each do |c|
  s = c.succ[0]
  letter_mapping[c] = VOWELS.include?(s) ? s.upcase : s
end
letter_mapping
  #=> { "a"=>"b", "b"=>"c", "c"=>"d", "d"=>"E", "e"=>"f", "f"=>"g", "g"=>"h", 
  #     "h"=>"I", "i"=>"j", "j"=>"k", "k"=>"l", "l"=>"m", "m"=>"n", "n"=>"O",
  #     "o"=>"p", "p"=>"q", "q"=>"r", "r"=>"s", "s"=>"t", "t"=>"U", "u"=>"v", 
  #     "v"=>"w", "w"=>"x", "x"=>"y", "y"=>"z", "z"=>"A"} 

所以,例如,letter_mapping['r'] #=> "s"

你会发现Ruby的写作方式是:

letters.each_with_object({}) do |c, letter_mapping|
  s = c.succ[0]
  letter_mapping[c] = VOWELS.include?(s) ? s.upcase : s
end
  #=> { "a"=>"b", ... "z"=>"A"} 

最后一件事。 Enumerable#map是包含Enumerable模块的每个类的实例方法。其中一个类是Array

Array.included_modules
  #=> [Enumerable, Kernel] 
Array.instance_methods.include?(:map)
  #=> true

Array使用了所有模块Enumerable的方法,就像它们已在Array 中定义一样。这就是为什么map在接收器是一个数组时工作的原因。

包含Enumerable的另一个类是Range

Range.included_modules
  #=> [Enumerable, Kernel] 
Range.instance_methods.include?(:map)
  #=> true

因此,而不是写:

letters = ('a'..'z').to_a

我们可以(应该)写:

letters = ('a'..'z')

以上所有代码都可以正常使用。

答案 1 :(得分:-1)

你可以尝试这个,它会用以下字母替换一个字母,它也会将元音大写。

def letter_changes(str)
  alphabets = ('a'..'z').to_a
  vowels = ["a","e","i","o","u"]

  for i in 0..(str.length-1) do
    index = (alphabets.index(str[i]) == (alphabets.size - 1) ? 0 : (alphabets.index(str[i]) + 1))
    str[i] = alphabets[index]
    str[i] = str[i].upcase if vowels.include?(str[i])
  end
  puts str
end

## call function
letter_changes("cadcarz")

## OUTPUT
dbEdbsA