以下是指定的问题:
使用Ruby语言,使用函数LetterChanges(str)获取传递的str参数,并使用以下算法对其进行修改。将字符串中的每个字母替换为字母表后面的字母(即c变为d,z变为a)。然后大写这个新字符串中的每个元音(a,e,i,o,u),最后返回这个修改后的字符串。*
我想我会分两部分攻击这个问题,但是我似乎无法弄清楚问题的前半部分我做错了什么!
这是我目前的代码。
......
i = 0
alphabet.each do |letter|
if str[i] == letter
str[i] = letter.next ##I also tried letter + 1
i += 1
end
end
......
此代码具有无限循环。我确实尝试了一些其他的东西,比如
{{1}}
答案 0 :(得分:1)
alphabet_lower = ["a".."z"]
这会创建一个Array
单个Range
元素,而不是您所期望的。这就是alphabet_lower[letter] == str[i]
永远不会成立的原因,导致无限循环。
将其更改为:
alphabet_lower = ("a".."z").to_a
由于字符串中还有空白字符,因此最好是:
alphabet_lower = ("a".."z").to_a + [' ']
答案 1 :(得分:0)
最有可能的是,您的if alphabet_lower[letter] == str[i]
没有匹配,因此您的letter
会增加到无穷大,并且您会获得无限循环。您可以在puts
上添加else
来验证这一点。如果你像俞昊所说的那样做,并放置你的输入和它的输出,这将有所帮助。另外,请发布LetterChanges
的调用脚本。
至于苏格拉底方式:
问题还在于,为什么if alphabet_lower[letter] == str[i]
没有匹配?你怎么能解决它? :)
答案 2 :(得分:0)
@Yu已经解释了你的问题。这是另一种使用String#gsub形式的方法,它使用哈希来替换字符串中的每个字符。
所有工作都将通过以下哈希来完成:
H = ('a'..'z').to_a.each_with_object(Hash.new { |h,k| k }) do |c,h|
h[c] = case c
when 'z' then 'A'
when 'd', 'h', 'n', 't' then c.next.upcase
else c.next
end
end
#=> {"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"}
哈希的构造很简单,除了可能创建它的行,这是Enumerable#each_with_object的参数:
Hash.new { |h,k| k }
这会创建一个带有默认值的空哈希。具体来说,如果h
不有一个键k
,h[k]
会返回默认值k
。我们可以看到它是如何工作的:
H['a'] #=> "b"
H['d'] #=> "E"
H['%'] #=> "%"
H['3'] #=> "3"
H['zombie'] #=> "zombie"
这允许我们写:
def convert(str)
str.gsub(/./, H)
end
产生所需的结果:
convert 'bcd tuv' #=> "cdE Uvw"
convert 'bcd3?tuv' #=> "cdE3?Uvw"
convert '123D ghi$' #=> "123D hIj$"
请注意,如果我们创建的H
没有默认值:
H = ('a'..'z').to_a.each_with_object({}) do |c,h|
h[c] = case c
...
end
end
哈希映射将是相同的,但我们将获得:
convert 'bcd tuv' #=> "cdEUvw"
convert 'bcd3?tuv' #=> "cdEUvw"
convert '123D ghi$' #=> "hIj"
这不是我们想要的。