交换单个字母单词的大小写
Swapping case of a single alphabetical word
我找到了这个用于交换大小写的代码,但我对它的工作原理有点困惑。
class Main {
private static String swapCase(String s) {
String r = "";
for (char c : s.toCharArray())
r += c ^= 32; // this line
return r;
}
public static void main(String[] args) {
System.out.println(swapCase("Hello"));
}
}
我知道它会循环遍历每个字符。但是,我无法绕过这条线(尤其是 XOR 运算符)
r += c ^= 32;
我的意思是32
有什么意义?它是如何交换大小写的?
这就是 ASCII set-up 的样子。
来自 a-z
的信件的第 6 位设置为 1
;而来自 A-Z
的字母的第 6 位设置为 0
.
32 = 100000 // the 6-th bit is set to 1
与 int
进行 XOR 将反转第 6 位。
你可以做一些调试,看看你自己:
for (char c : s.toCharArray()) {
System.out.println(Integer.toBinaryString((int) c));
c ^= 32; // this line
System.out.println(Integer.toBinaryString((int) c));
}
对于 ASCII 编码,32 是 lower-case 字母和大写字母之间的区别。它是 2 的幂,它的二进制表示是单个 1 位:
0010 0000
.
通过应用 XOR 赋值运算符,您可以更改字符值中的这位。有效加法(如果c
中的位为0)或减法(c
中的位为1) 32.
这对于字母 A-Z 和 a-z 可以很好地工作,但很可能对输入中的大多数其他字符来说都是无意义的。
看看这个table你就会明白为什么
a = 01100001 A = 01000001
b = 01100010 B = 01000010
c = 01100011 C = 01000011
d = 01100100 D = 01000100
e = 01100101 E = 01000101
f = 01100110 F = 01000110
g = 01100111 G = 01000111
h = 01101000 H = 01001000
i = 01101001 I = 01001001
j = 01101010 J = 01001010
k = 01101011 K = 01001011
l = 01101100 L = 01001100
m = 01101101 M = 01001101
n = 01101110 N = 01001110
o = 01101111 O = 01001111
p = 01110000 P = 01010000
q = 01110001 Q = 01010001
r = 01110010 R = 01010010
s = 01110011 S = 01010011
t = 01110100 T = 01010100
u = 01110101 U = 01010101
v = 01110110 V = 01010110
w = 01110111 W = 01010111
x = 01111000 X = 01011000
y = 01111001 Y = 01011001
z = 01111010 Z = 01011010
上下版本唯一不同的是第5位(从0开始数)。这就是为什么使用简单的 XOR 掩码,您可以来回更改大小写的原因。
我找到了这个用于交换大小写的代码,但我对它的工作原理有点困惑。
class Main {
private static String swapCase(String s) {
String r = "";
for (char c : s.toCharArray())
r += c ^= 32; // this line
return r;
}
public static void main(String[] args) {
System.out.println(swapCase("Hello"));
}
}
我知道它会循环遍历每个字符。但是,我无法绕过这条线(尤其是 XOR 运算符)
r += c ^= 32;
我的意思是32
有什么意义?它是如何交换大小写的?
这就是 ASCII set-up 的样子。
来自 a-z
的信件的第 6 位设置为 1
;而来自 A-Z
的字母的第 6 位设置为 0
.
32 = 100000 // the 6-th bit is set to 1
与 int
进行 XOR 将反转第 6 位。
你可以做一些调试,看看你自己:
for (char c : s.toCharArray()) {
System.out.println(Integer.toBinaryString((int) c));
c ^= 32; // this line
System.out.println(Integer.toBinaryString((int) c));
}
对于 ASCII 编码,32 是 lower-case 字母和大写字母之间的区别。它是 2 的幂,它的二进制表示是单个 1 位:
0010 0000
.
通过应用 XOR 赋值运算符,您可以更改字符值中的这位。有效加法(如果c
中的位为0)或减法(c
中的位为1) 32.
这对于字母 A-Z 和 a-z 可以很好地工作,但很可能对输入中的大多数其他字符来说都是无意义的。
看看这个table你就会明白为什么
a = 01100001 A = 01000001
b = 01100010 B = 01000010
c = 01100011 C = 01000011
d = 01100100 D = 01000100
e = 01100101 E = 01000101
f = 01100110 F = 01000110
g = 01100111 G = 01000111
h = 01101000 H = 01001000
i = 01101001 I = 01001001
j = 01101010 J = 01001010
k = 01101011 K = 01001011
l = 01101100 L = 01001100
m = 01101101 M = 01001101
n = 01101110 N = 01001110
o = 01101111 O = 01001111
p = 01110000 P = 01010000
q = 01110001 Q = 01010001
r = 01110010 R = 01010010
s = 01110011 S = 01010011
t = 01110100 T = 01010100
u = 01110101 U = 01010101
v = 01110110 V = 01010110
w = 01110111 W = 01010111
x = 01111000 X = 01011000
y = 01111001 Y = 01011001
z = 01111010 Z = 01011010
上下版本唯一不同的是第5位(从0开始数)。这就是为什么使用简单的 XOR 掩码,您可以来回更改大小写的原因。