[英]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"
。
用a
到z
以外的任何字符或大写字母尝试此代码。 它会崩溃,因为字符的 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.