我必须将字母表中的每个字母替换为字母表后面的字母(即c
变为d
,z
变为a
),将每个元音大写(a
,e
,i
,o
,u
),并返回修改后的字符串。我试图在不调用sort
或find
等任何功能的情况下找到解决方案。
我有这个:
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
但我迷路了。任何帮助表示赞赏。
答案 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]
现在让我们使用以下方法填写代码:
"b".ord #=> 98
,"b".succ #=> "c"
,因为"c".ord #=> 99
。自"z".succ #=> 'aa'
起,我们需要对待&#34; z&#34;作为一个特例。 String#succ
与String#next相同。 true
或false
,具体取决于include?
的参数(字符串)是否包含在接收者中。例如,"cat".include?("at") #=> true; "cat".include?("a") #=> true; "cat".include?("z") #=> false
。请注意,VOWELS
,因为它以大写字母开头,是一个常量。
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#ord和Integer#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