You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

凯撒密码(Caesar cipher)开发问题:非字母字符重复添加如何修复?

问题分析与修复方案

你的代码核心问题是多余的内层循环for (int i = 1; i < chars.length - 1; i++),这个循环会让每个输入字符被重复处理chars.length-2次,直接导致非字母字符被多次追加到结果字符串里。另外还有加密逻辑的疏漏(比如字母超出范围时未循环回字母表开头)和循环条件的冗余。

修复后的代码

public static String encrypt(String text, int number) {
    StringBuilder str = new StringBuilder(); // 用StringBuilder替代字符串拼接,效率更高
    char[] chars = text.toCharArray();
    char[] lowerAlph = "abcdefghijklmnopqrstuvwxyz".toCharArray();
    char[] upperAlph = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
    int alphabetLen = lowerAlph.length; // 字母表长度固定为26

    for (char c : chars) {
        boolean isLetter = false;

        // 检查小写字母
        for (int k = 0; k < alphabetLen; k++) {
            if (c == lowerAlph[k]) {
                // 计算加密后的位置,取模避免超出字母范围
                int newPos = (k + number) % alphabetLen;
                // 处理负数偏移的情况(如果number是负数)
                if (newPos < 0) {
                    newPos += alphabetLen;
                }
                str.append(lowerAlph[newPos]);
                isLetter = true;
                break; // 找到匹配后直接跳出循环
            }
        }

        // 如果不是小写字母,检查大写字母
        if (!isLetter) {
            for (int k = 0; k < alphabetLen; k++) {
                if (c == upperAlph[k]) {
                    int newPos = (k + number) % alphabetLen;
                    if (newPos < 0) {
                        newPos += alphabetLen;
                    }
                    str.append(upperAlph[newPos]);
                    isLetter = true;
                    break;
                }
            }
        }

        // 非字母字符直接追加
        if (!isLetter) {
            str.append(c);
        }
    }

    return str.toString();
}

关键修复点

  • 移除了无意义的内层循环,每个字符只被处理一次
  • 用StringBuilder替代字符串拼接,避免频繁创建字符串对象,提升性能
  • 修复加密逻辑:通过取模运算让字母在超出范围时循环回字母表开头,同时兼容负数偏移量
  • 拆分大小写字母的检查逻辑,找到匹配后立即跳出循环,减少不必要的遍历
  • 统一字母表长度的引用,避免硬编码数字26

简化版(更高效的实现)

其实不需要预先定义字母数组,直接通过字符的ASCII范围判断更简洁高效:

public static String encrypt(String text, int number) {
    StringBuilder str = new StringBuilder();
    int alphabetLen = 26;

    for (char c : text.toCharArray()) {
        if (c >= 'a' && c <= 'z') {
            int newPos = (c - 'a' + number) % alphabetLen;
            newPos = newPos < 0 ? newPos + alphabetLen : newPos;
            str.append((char) ('a' + newPos));
        } else if (c >= 'A' && c <= 'Z') {
            int newPos = (c - 'A' + number) % alphabetLen;
            newPos = newPos < 0 ? newPos + alphabetLen : newPos;
            str.append((char) ('A' + newPos));
        } else {
            // 非字母字符直接追加
            str.append(c);
        }
    }

    return str.toString();
}

这个版本通过计算字符相对于字母表起始位置的偏移量直接加密,完全避免了数组遍历的开销,代码更简洁易读。

内容的提问来源于stack exchange,提问作者cordesjan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 16:25:37