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

如何用位运算验证ASCII字符串字符唯一性?大小写字母场景程序报错

搞定位运算验证字符唯一性的大小写问题

嘿,我明白你遇到的麻烦了——你的位运算逻辑是基于原始ASCII值来标记字符是否出现的,但大小写字母的ASCII本身就不一样(比如'A'是65,'a'是97),所以代码会把它们当成完全不同的字符。如果你的需求是不区分大小写来检查唯一性(比如把T和t算重复),那当前逻辑就没处理这种情况,自然会“失效”。

下面咱们一步步解决这个问题:

先补全区分大小写的正确代码

首先把你没写完的代码补全,这是严格区分大小写时的正确实现,能准确检测原始ASCII字符的重复:

import java.util.Scanner;

public class Q1_1 { 
    public static void main(String[] args) { 
        long firstHalf = 0; // 存ASCII 0-63的标记位,64位刚好覆盖
        long secondHalf = 0; // 存ASCII 64-127的标记位,偏移后也用64位覆盖
        Scanner sc = new Scanner(System.in); 
        String input = sc.nextLine(); 
        boolean hasDuplicate = false;
        
        for(int i = 0; i < input.length(); i++) { 
            char currentChar = input.charAt(i);
            int asciiVal = (int) currentChar;
            
            // 先检查是否是合法ASCII字符(0-127)
            if (asciiVal < 0 || asciiVal > 127) {
                System.out.println("输入包含非ASCII字符,请检查!");
                hasDuplicate = true;
                break;
            }
            
            if (asciiVal < 64) {
                // 操作firstHalf的对应位
                long mask = 1L << asciiVal;
                if ((firstHalf & mask) != 0) {
                    // 该位已经被标记过,说明字符重复
                    hasDuplicate = true;
                    break;
                }
                firstHalf |= mask; // 标记该位为已出现
            } else {
                // 把64-127转成0-63的偏移量,操作secondHalf
                int offset = asciiVal - 64;
                long mask = 1L << offset;
                if ((secondHalf & mask) != 0) {
                    hasDuplicate = true;
                    break;
                }
                secondHalf |= mask;
            }
        }
        
        if (hasDuplicate) {
            System.out.println("字符串包含重复字符(区分大小写)");
        } else {
            System.out.println("字符串所有字符唯一(区分大小写)");
        }
        sc.close();
    }
}

修改为不区分大小写的验证逻辑

如果你的需求是忽略大小写(比如Test里的T和t算重复),只需要在处理每个字符时,先统一转成大写或小写,再获取ASCII值就行,核心改动就一行:

import java.util.Scanner;

public class Q1_1 { 
    public static void main(String[] args) { 
        long firstHalf = 0;
        long secondHalf = 0;
        Scanner sc = new Scanner(System.in); 
        String input = sc.nextLine(); 
        boolean hasDuplicate = false;
        
        for(int i = 0; i < input.length(); i++) { 
            char currentChar = input.charAt(i);
            // 关键:统一转成小写(也可以用toUpperCase),让大小写字母映射到同一个ASCII值
            char normalizedChar = Character.toLowerCase(currentChar);
            int asciiVal = (int) normalizedChar;
            
            if (asciiVal < 0 || asciiVal > 127) {
                System.out.println("输入包含非ASCII字符,请检查!");
                hasDuplicate = true;
                break;
            }
            
            if (asciiVal < 64) {
                long mask = 1L << asciiVal;
                if ((firstHalf & mask) != 0) {
                    hasDuplicate = true;
                    break;
                }
                firstHalf |= mask;
            } else {
                int offset = asciiVal - 64;
                long mask = 1L << offset;
                if ((secondHalf & mask) != 0) {
                    hasDuplicate = true;
                    break;
                }
                secondHalf |= mask;
            }
        }
        
        if (hasDuplicate) {
            System.out.println("字符串包含重复字符(不区分大小写)");
        } else {
            System.out.println("字符串所有字符唯一(不区分大小写)");
        }
        sc.close();
    }
}

为啥这么做?

  • 用两个long是因为它刚好64位,两个加起来128位,完美对应0-127的ASCII字符,每个位标记一个字符是否出现过,完全不用额外数据结构,符合你的需求。
  • 不区分大小写的核心就是归一化字符:把所有字母转成同一种大小写,这样大小写字母会被映射到同一个ASCII值,位运算就能检测出它们是重复的。
  • 加了非ASCII字符的判断,避免超出范围的字符导致位运算越界出错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:54:08