这是一个问题:使用Ruby语言,使用函数CaesarCipher(str,num)获取str参数并使用num参数作为移位数对其执行Caesar Cipher移位。凯撒密码的工作原理是将字母N中的每个字母移位到字母表中(在这种情况下,N将为num)。标点符号,空格和大小写应保持不变。例如,如果字符串是" Caesar Cipher"和num是2,输出应该是" Ecguct Ekrjgt"
这是我的代码
def CaesarCipher(str,num)
alphabet = ("a".."z").to_a.join("")
alphabetupcase = ("a".."z").to_a.join("").upcase
i=0
result = ""
while i < str.length
if alphabet.include?(str[i])
result += alphabet[alphabet.index(str[i]) + num]
elsif alphabetupcase.include?(str[i])
result += alphabetupcase[alphabetupcase.index(str[i]) + num]
else
result += str[i]
end
i += 1
end
# code goes here
return result
end
我一直收到这个错误(eval):11:(eval):11:+': can't convert Fixnum into String (TypeError) from (eval):11:in
CaesarCipher&#39;来自(评估):26
这有什么问题?如何修复此代码? 你能建议一个更好的解决方案,记住我是Ruby的初学者吗? 提前谢谢大家
答案 0 :(得分:1)
您的代码不起作用,因为您错过了模数操作 - 如果您移动字母&#39; z&#39; 2,你应该得到&#39; b&#39;。在这种情况下,你的程序失败了。计算新字母索引的算法是:(index + shift) modulo alphabet_size
。
但我会这样做:
def caesar (str, num)
str.split('').collect do |character|
case character
when 'a'..'z', 'A'..'Z'
base_ascii = if character == character.upcase then 'A'.ord else 'a'.ord end
(((character.ord - base_ascii + num) % ('a'..'z').count) + base_ascii).chr
else
character
end
end.join('')
end
首先,迭代字符串的每个字符。如果是一个字母,请计算班次(注意base_ascii
,这是&#39; A&#39;或&#39; a&#39;的ASCII代码,取决于班次是为了更低 - 或大写),它只是字母(character.ord
- base_ascii)的索引加上shif(num
)模数字母表中的模数(('a'..'z').count
)。如果字符不是字母,那么空格,标点符号,将其保持不变。
答案 1 :(得分:0)