我有以下代码,使用位向量在字符串中查找唯一字符。我们假设它只是一个带小写字母的ASCII字符集。
我很难理解下面的位向量的使用。即使在通过程序进行调试并遵循更改后,每个循环之后都会经历变量。
// assuming that the characters range from a-z
static boolean isUniqueBitVector(String str) {
int checker = 0;
for(int i = 0; i < str.length(); i++) {
int val = str.charAt(i) - 'a';
if((checker & (1 << val)) > 0) {
return false;
} else {
checker |= (1 << val);
}
}
return true;
}
将val(字符串中每个字符的int表示)左移的原因是什么,并将其与检查器(初始化为0)进行“并”并在其他地方对其进行“或”运算。块。
答案 0 :(得分:4)
checker
是一个32位整数,我们在其中指定最低的26来存储每个字母a-z
的标志。我们可以使用这个位,因为一个字母只能是非唯一的一次。
int val = str.charAt(i) - 'a';
计算与当前字母对应的位的索引。这是输入仅包含a-z
的假设。val
将是0到25之间的数字。
通常,(1 << val)
是与所选字母对应的位。 <<
是左移算子。它用于移动1,只有一个位,val
位置在左侧。因此,例如,1<<3
将为8.实际上,左移相当于乘以2的幂。
(checker & (1 << val))
验证所选位是否打开。 &
运算符按位称调用。它结合了两个数字,并将两者中的任何位设置为打开。请记住,1 << val
只打开了一个位。如果checker
已经打开了同一位,那么该结果和checker
的结果将是非零的唯一方法。在那种情况下,我们返回false,因为重复了一封信。
如果找到新信件,我们需要打开checker
中的正确位。这就是checker |= (1 << val);
的作用。如果在任一操作数中打开,则按位或运算符|
将在结果中打开一个位。同样,1 << val
只有一位。因此,或者是复制checker
并打开那一位(无论它是否已经打开)的结果。
您在此处看到的所有操作都是非常常见的习惯用法。希望我的解释在某种程度上帮助了你,因为你几乎肯定会在任何简单的代码中看到非常相似的东西。