繁体   English   中英

为什么我们在 java 中使用 string.charAt(index)-'a'?

[英]Why do we use string.charAt(index)-'a' in java?

public static void main(String[] args) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String s = br.readLine();
    int[] arr = new int[26];
    for(int i=0;i<s.length();i++)
        arr[s.charAt(i)-'a']++;
    
    int odds = 0;
    for(int i=0;i<26;i++)
        if(arr[i]%2!=0)
            odds++;
    
    if(odds%2==1 || odds==0)
        System.out.println("First");
    else
        System.out.println("Second");

}

我看到了这段代码,发现这部分令人困惑。 那么你能告诉我为什么我们要用这个吗? 'a'arr[s.charAt(i)-'a']++;中的意义是什么?

此代码为字母表中的每个字母创建了一个类似直方图的计数器。 尝试打印一个字符,例如'a' ,如下所示:

System.out.println((int)'a'); // Output: 97

每个char都有一个对应的 Unicode 值,介于 0 和 65,535 之间。 减去'a' (或 97)将字母表中的每个字母缩放到与arr数组中的“桶”相对应的 0-26 范围。 这是一个例子:

System.out.println('z' - 'a'); // Output: 25 (the last bucket in the array)
System.out.println('a' - 'a'); // Output: 0 (the first bucket in the array)

代码中的第二个循环检查每个计数的奇偶性以确定哪些是奇数。 最后,最终打印条件检查出现次数是否为奇数的字母总数。 如果此总数为0或本身为奇数,则打印"First" ,否则打印"Second"

az以外的任何字符或大写字母尝试此代码。 它会崩溃,因为字符的 ASCII 表示超出了数组的大小,您将得到一个IndexOutOfBoundsException

下面是一个示例程序,展示了如何构建直方图以及如何通过加法将其输出转换回字母:

class Main {
    public static void main(String[] args) {
        String s = "snuffleupagus";
        int[] arr = new int[26];

        for (int i = 0; i < s.length(); i++) {
            arr[s.charAt(i)-'a']++;
        }

        for (int i = 0; i < arr.length; i++) {
            System.out.println((char)(i + 'a') + ": " + arr[i]);
        }
    }
}

输出:

a: 1
b: 0
c: 0
d: 0
e: 1
f: 2
g: 1
h: 0
i: 0
j: 0
k: 0
l: 1
m: 0
n: 1
o: 0
p: 1
q: 0
r: 0
s: 2
t: 0
u: 3
v: 0
w: 0
x: 0
y: 0
z: 0

arr由一个大小为 26 的 int 数组组成,这也是英文字母表中字母的数量。 该循环所做的就是计算字母的频率,通过它们在字母表中的索引表示, arr[0]'a'arr[1]'b'等。

它的技术细节可以简单地解释一下。 s.charAt(i)在指定位置i返回一个char实例。 在 Java 中, char也可以表示为 byte。 然后减法从i处的当前字符中获取 'a' 的 ASCII 值(表示为byte )。 所以你最终得到的是'a' - 'a' == 0'b' - 'a' == 1 ,等等。

请注意,这可能不是计算字符数的最佳方法,因为字符串可以包含的不仅仅是小写字母,例如大写字母,还有更多的符号。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM