基于Rosetta Code的Ruby凯撒密码未生效,输出原字符串求助
问题分析与修复方案
你的凯撒密码代码之所以只输出原始字符串,核心问题是仅处理了大写字母,但tr方法只会替换完全匹配的字符——如果输入是小写、混合大小写,字母部分因为找不到匹配的替换规则,就会直接返回原内容;非字母字符本来就会被原样保留,这个是正常的。
具体问题点:
- 你的
ALPHABET只定义了A-Z的大写字母集合,tr只能替换这些大写字符,小写字母完全不会被处理。 - 代码里的
"#{word}"是多余的,word已经是字符串,直接调用caesar_cipher方法即可。 - 缺少无效输入的处理分支,用户输入非
encrypt/decrypt的内容时程序会无输出。
修复后的完整代码
class String # 拆分大小写字母表,分别处理 UPPER_ALPHABET = ("A".."Z").to_a LOWER_ALPHABET = ("a".."z").to_a def caesar_cipher(num) # 分别旋转大小写字母表,生成替换目标 rotated_upper = UPPER_ALPHABET.rotate(num).join rotated_lower = LOWER_ALPHABET.rotate(num).join # 合并大小写的源字符串和目标字符串,一次完成替换 self.tr(UPPER_ALPHABET.join + LOWER_ALPHABET.join, rotated_upper + rotated_lower) end end # 获取用户输入(gets.chomp已经是字符串,无需to_s) word = gets.chomp encrypted = word.caesar_cipher(8) decrypted = word.caesar_cipher(-8) puts "Encrypt or Decrypt?" choice = gets.chomp.downcase # 处理用户选择,补充无效输入分支 if choice == "encrypt" puts encrypted elsif choice == "decrypt" puts decrypted else puts "Invalid choice! Please enter 'encrypt' or 'decrypt'." end
修复说明
- 支持大小写处理:新增
LOWER_ALPHABET集合,确保小写字母也能被旋转替换,不管输入是大写、小写还是混合格式,都能正确加密/解密。 - 简化代码:去掉了多余的
to_s和字符串插值"#{word}",让代码更简洁。 - 增强健壮性:添加了
else分支处理无效输入,避免程序静默无输出。
举个测试例子:如果输入Hello World!,选择encrypt会输出Pmttw Bmzxp!,选择decrypt会还原回Hello World!,完全符合凯撒密码的预期效果。
内容的提问来源于stack exchange,提问作者Austin Larson
相关产品推荐
相关产品推荐

