简体   繁体   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");

}

I saw this snippet of code and found this part confusing.我看到了这段代码,发现这部分令人困惑。 So could you please tell me why do we use this and what is the significance of 'a' in arr[s.charAt(i)-'a']++;那么你能告诉我为什么我们要用这个吗? 'a'arr[s.charAt(i)-'a']++;中的意义是什么? ?

This code makes a histogram-like counter for each letter of the alphabet.此代码为字母表中的每个字母创建了一个类似直方图的计数器。 Try printing a char such as 'a' as follows:尝试打印一个字符,例如'a' ,如下所示:

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

Each char has a corresponding Unicode value between 0 and 65,535.每个char都有一个对应的 Unicode 值,介于 0 和 65,535 之间。 Subtracting 'a' (or, 97) scales each letter in the alphabet to the 0-26 range that corresponds to the "buckets" in the arr array.减去'a' (或 97)将字母表中的每个字母缩放到与arr数组中的“桶”相对应的 0-26 范围。 Here's an example:这是一个例子:

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)

The second loop in the code checks the parity of each count to determine which are odd.代码中的第二个循环检查每个计数的奇偶性以确定哪些是奇数。 Lastly, the final print conditional checks if the total number of letters with an odd number of occurrences.最后,最终打印条件检查出现次数是否为奇数的字母总数。 If this total is 0 or itself odd, print "First" , else "Second" .如果此总数为0或本身为奇数,则打印"First" ,否则打印"Second"

Try this code with any character outside of a to z or with a capital letter.az以外的任何字符或大写字母尝试此代码。 It'll crash because the ASCII representation of the character is out of the array's size and you'll wind up with an IndexOutOfBoundsException .它会崩溃,因为字符的 ASCII 表示超出了数组的大小,您将得到一个IndexOutOfBoundsException

Here's a sample program showing how the histogram is built and converts its output back to letters through addition:下面是一个示例程序,展示了如何构建直方图以及如何通过加法将其输出转换回字母:

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]);
        }
    }
}

Output:输出:

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 is made of an int array of size 26, which is also the number of letters in English alphabet. arr由一个大小为 26 的 int 数组组成,这也是英文字母表中字母的数量。 All that loop is doing is counting the frequency of the letters, represented via their index in the alphabet, arr[0] being 'a' , arr[1] being 'b' , etc.该循环所做的就是计算字母的频率,通过它们在字母表中的索引表示, arr[0]'a'arr[1]'b'等。

The technicalities of it can be explained simply.它的技术细节可以简单地解释一下。 s.charAt(i) is returning a char instance at the specified position i . s.charAt(i)在指定位置i返回一个char实例。 A char can also be represented as a byte in Java.在 Java 中, char也可以表示为 byte。 The subtraction then takes the ASCII value (represented as a byte ) of 'a' from the current character at i .然后减法从i处的当前字符中获取 'a' 的 ASCII 值(表示为byte )。 So what you end up getting is 'a' - 'a' == 0 , 'b' - 'a' == 1 , and so on.所以你最终得到的是'a' - 'a' == 0'b' - 'a' == 1 ,等等。

Please note that this is probably not the best way to count characters as a string can contain more than just the lowercase letters, eg uppercase letters, and many more symbols.请注意,这可能不是计算字符数的最佳方法,因为字符串可以包含的不仅仅是小写字母,例如大写字母,还有更多的符号。

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

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