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

凯撒密码程序空格处理问题求助:遇空格跳过加密并保留

凯撒密码程序空格处理问题解决

问题描述

编写的凯撒密码程序从文本文件读取输入,当输入字符串包含空格时,程序会错误地对空格进行加密,导致输出异常。例如输入“hello world”、偏移量为4时,实际输出为lippsdasvh,而期望输出为LIPPS ASVPH。需要实现遇到空格时直接保留,不执行加密操作。

问题分析

原代码中没有判断空格的逻辑,当遇到空格时,ALPHABET.indexOf(' ')会返回-1,后续计算encryptPos = (4 + (-1)) %29 =3,会取字母表中索引3的字符,导致空格被错误替换。

解决方案

核心修改点如下:

  • 遍历字符时先判断是否为空格,若是则直接添加到结果字符串,跳过加密流程
  • 补充解密逻辑(对应EncrDecrpt变量的使用)
  • 使用StringBuilder优化字符串拼接效率
  • 处理大小写转换,匹配期望的大写输出
  • 避免全局变量,减少不必要的静态变量

修改后的完整代码

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class CaesarCipher {
    // 定义英文字母表,根据需要可替换为土耳其/西班牙字母表
    private static final String ENGLISH_ALPHABET = "abcdefghijklmnopqrstuvwxyz";

    public static void main(String[] args) throws FileNotFoundException {
        File inputFile = new File("filename.txt");
        Scanner scan = new Scanner(inputFile);

        while (scan.hasNextLine()) {
            String line = scan.nextLine();
            String[] parts = line.split(":");

            if (parts.length != 4) {
                System.out.println("无效的输入格式,请检查文件内容");
                continue;
            }

            int shiftNumber = Integer.parseInt(parts[0]);
            int encrDecrpt = Integer.parseInt(parts[1]);
            int language = Integer.parseInt(parts[2]);
            String plainText = parts[3];

            // 根据语言选择对应字母表
            String alphabet = ENGLISH_ALPHABET;
            if (language == 1) { // 假设1代表土耳其,可自行调整
                // alphabet = "abcçdefgğhıijklmnoöprsştuüvyz";
            } else if (language == 2) { // 2代表西班牙
                // alphabet = "abcdefghijklmnñopqrstuvwxyz";
            }

            String result = processCaesar(plainText, shiftNumber, encrDecrpt, alphabet);
            System.out.println("处理结果: " + result);
        }
        scan.close();
    }

    public static String processCaesar(String plainText, int shiftNumber, int encrDecrpt, String alphabet) {
        StringBuilder result = new StringBuilder();
        int alphabetLength = alphabet.length();

        for (int i = 0; i < plainText.length(); i++) {
            char c = plainText.charAt(i);
            // 遇到空格直接添加,跳过加密/解密
            if (c == ' ') {
                result.append(' ');
                continue;
            }

            // 转换为小写后查找索引
            char lowerC = Character.toLowerCase(c);
            int pos = alphabet.indexOf(lowerC);
            // 如果字符不在字母表中,直接保留原字符
            if (pos == -1) {
                result.append(c);
                continue;
            }

            int processedPos;
            if (encrDecrpt == 1) { // 1代表加密,可自行调整标识
                processedPos = (pos + shiftNumber) % alphabetLength;
                // 处理负数偏移(如果shiftNumber为负)
                if (processedPos < 0) {
                    processedPos += alphabetLength;
                }
            } else { // 解密
                processedPos = (pos - shiftNumber) % alphabetLength;
                // 确保索引非负
                if (processedPos < 0) {
                    processedPos += alphabetLength;
                }
            }

            // 根据原字符的大小写决定输出大小写
            char processedChar = alphabet.charAt(processedPos);
            if (Character.isUpperCase(c)) {
                processedChar = Character.toUpperCase(processedChar);
            }
            result.append(processedChar);
        }
        return result.toString();
    }
}

关键修改说明

  1. 空格处理:在循环中增加if (c == ' ')判断,直接将空格追加到结果中,跳过后续加密逻辑。
  2. 字符合法性判断:如果字符不在字母表中(pos == -1),也直接保留原字符,增强程序兼容性。
  3. 解密逻辑实现:根据encrDecrpt变量判断是加密还是解密,解密时调整偏移量计算方式,确保索引为非负。
  4. 大小写保持:根据原字符的大小写,将处理后的字符转换为对应大小写,匹配期望的LIPPS ASVPH格式。
  5. 性能优化:使用StringBuilder替代字符串+=操作,避免频繁创建字符串对象,提升效率。
  6. 代码结构优化:移除不必要的全局静态变量,将字母表定义为常量,增加输入格式校验,提升代码健壮性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 04:37:48