在Ruby on rails中递增的字母字符串



我要解决的任务:

编写一个程序,接受一个字符串,执行转换并返回它。对于参数字符串的每个字母,按字母顺序切换下一个字母。"z"变成了"a","z"变成了"a"。

def rotone(param_1)
a = ""
param_1.each_char do |x|
if x.count("a-zA-Z") > 0
a << x.succ
else
a << x
end
end
a
end

我取这个

Input:  "AkjhZ zLKIJz , 23y "
Expected Return Value: "BlkiA aMLJKa , 23z "
Return Value:          "BlkiAA aaMLJKaa , 23z "

当迭代器找到'z'或'z'时,它自增两次z ->a或Z ->AA

input = "AkjhZ zLKIJz , 23y"

代码
p input.tr('a-yA-YzZ','b-zB-ZaA')

输出
"BlkiA aMLJKa , 23z"

你的问题是字符串#succ(又名字符串#next)的设计方式不能满足你的目的,当收件人是'z''Z':

'z'.succ #=> 'aa'
'Z'.succ #=> 'AA'

如果你用a << x.succ[0]代替a << x.succ,你会得到想要的结果。


你可以考虑这样写。

def rotone(param_1)
param_1.gsub(/./m) { |c| c.match?(/[a-z]/i) ? c.succ[0] : c }
end

String#gsub的参数是一个匹配每个字符的正则表达式(因此每个字符都传递给gsub的块)1

参见String#match?正则表达式/[a-z]/i匹配字符类[a-z]中的每个字符。选项i使匹配与大小写无关的,因此也匹配大写字母。


这是另一种使用两个定义为常量的哈希值的方法。

CODE = [*'a'..'z', *'A'..'Z'].each_with_object({}) do |c,h|
h[c] = c.succ[0]
end.tap { |h| h.default_proc = proc { |_h,k| k } }
#=> {"a"=>"b", "b"=>"c",..., "y"=>"z", "z"=>"a",
#    "A"=>"B", "B"=>"C",..., "Y"=>"Z", "Z"=>"A"}
DECODE = CODE.invert.tap { |h| h.default_proc = proc { |_h,k| k } }
#=> {"b"=>"a", "c"=>"b", ..., "z"=>"y", "a"=>"z",
#    "B"=>"A", "C"=>"B", ..., "Z"=>"Y", "A"=>"Z"}

例如,

CODE['e'] #=> "f"
CODE['Z'] #=> "A"
CODE['?'] #=> "?"
DECODE['f'] #=> "e"
DECODE['A'] #=> "Z"
DECODE['?'] #=> "?"

让我们尝试使用gsub,CODEDECODE与示例字符串。

str = "The quick brown dog Zelda jumped over the lazy fox Arnie"
rts = str.gsub(/./m, CODE)
#=> "Uif rvjdl cspxo eph Afmeb kvnqfe pwfs uif mbaz gpy Bsojf"
rts.gsub(/./m, DECODE)
#=> "The quick brown dog Zelda jumped over the lazy fox Arnie"

参见hash# merge, object# tap, hash# default_proc=, hash# invert和sting# gsub的形式,它将哈希值作为可选的第二个参数。

默认进程添加到散列h中,如果h没有k键,则h[k]返回k。如果在没有默认过程的情况下定义CODE

CODE = [*'a'..'z', *'A'..'Z'].each_with_object({}) { |c,h| h[c] = c.succ[0] }
#=> {"a"=>"b", "b"=>"c",..., "y"=>"z", "z"=>"a",
#    "A"=>"B", "B"=>"C",..., "Y"=>"Z", "Z"=>"A"}

gsub将跳过非字母的字符:

rts = str.gsub(/./m, CODE)
#=> "UifrvjdlcspxoephAfmebkvnqfepwfsuifmbazgpyBsojf"

如果没有默认进程,我们将不得不写

rts = str.gsub(/./m) { |s| CODE.fetch(s, s) }
#=> "Uif rvjdl cspxo eph Afmeb kvnqfe pwfs uif mbaz gpy Bsojf"

看到散列#取回。

<一口>1。正则表达式/./匹配除行结束符以外的所有字符。添加选项m(/./m)将导致.也匹配行终止符。

相关内容

  • 没有找到相关文章

最新更新