我做了一个简单的ROT13计划,我不明白一件事:
a = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
(a.length+1).times do |i|
print a[i + 13]
if i>13
print a[i %14]
end
end
输出:
NOPQRSTUVWXYZABCDEFGHIJKLM
如果我在+1
之后没有添加a.length
,则迭代以字母L
结束。但是,如果我在迭代中使用print a[i]
,则通常以A
开头,以Z
结尾,不需要添加+1
。
有人可以为我解释这个谜吗?
答案 0 :(得分:3)
如您所知,.times
循环调用指定次数的块,向每次迭代传递递增的值。
如果我们说26.times {|i| puts i}
,它会打印0到25之间的值。最多但不包括最后一个值。
现在让我们走一圈。在第一次迭代时,i
为0.因此我们打印字符串的第14个字符"N"
(在索引13处,从零开始)。我们没有进入条件,因为0不大于13.在第二次迭代中,我们打印第15个字符"O"
。并继续这样做,直到我们达到i=14
。
此时,"魔术"开始。首先,我们尝试打印字符串的第27个字符。没有这样的角色所以我们什么都没打印。然后触发条件,我们进去。
i % 14
等于0,因此我们打印第0个字符"A"
。下一次迭代我们在索引1(15 % 14
)处打印字符,依此类推,直到.times
完成其迭代并停止调用块。现在,为了使这个逻辑起作用,i
的最后一个值必须为26,这样我们就可以获得i % 14
中的12个并打印"M"
。
整个字符串的长度为26.请记住,.times
计算但不包括数字?这就是为什么我们在长度上添加一个,以便它从0到26的数量。这是个谜。
有许多方法可以改进此代码,您可以及时了解它们。 :)
我知道代码看起来很奇怪。当然,还有一个错误。当i
为13时,我们第一次不打印和我们不会进入该状态。我们浪费了一次迭代。这是"关闭1"的经典例子。一类错误。这里的代码的固定版本没有浪费迭代而且没有任何谜团:
a.length.times do |i|
print a[i + 13]
if i > 12
print a[i % 13]
end
end
答案 1 :(得分:2)
我只需要一个快速腐烂的内衬纸,这是Google的第一个结果。我一直在搜索,发现@xfaider的一个超小型显示器对我的目的已经足够好了。
只需将其张贴在这里,供下一个想要单线的人使用。
string.tr("A-Za-z", "N-ZA-Mn-za-m")
答案 2 :(得分:1)
字母串的长度为26,但索引为0。在这种情况下,字母Z是索引号25.时间方法不会运行最后的迭代(26)。因此,为了解释这一点,我们在长度上添加+1。