java新手-尝试理解:checker |=(1<;<;val)
下面的代码将检查字符串中是否有重复字符,但我不理解if子句:java新手-尝试理解:checker |=(1<;<;val),java,Java,下面的代码将检查字符串中是否有重复字符,但我不理解if子句: public static boolean isUniqueChars(String str) { int checker = 0; for (int i = 0; i < str.length(); ++i) { int val = str.charAt(i) - 'a'; if ((checker & (1 << val))
public static boolean isUniqueChars(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;
checker |= (1 << val);
}
return true;
}
public静态布尔值isUniqueChars(String str){
int-checker=0;
对于(int i=0;i checker |=(11这将第‘val’位从右侧设置为1
1意思是在值checker
和(1checker|=(1我也在翻阅这本书,最后在谷歌上搜索清楚的解释。最后我理解了这个概念
这里是方法
注意:
在下面的代码中,我们将假定字符串仅为小写字母“a”到“z”。这将允许我们仅使用单个int
Java整数的大小为32
小写字母的数量为26
因此,我们可以在一个整数中清楚地设置0/1(真或假)值
十进制记数法
它类似于bool[32]。
bool使用1个字节。因此需要32个字节来存储访问过的bool[32]
位屏蔽是一种空间优化
让我们开始:
您正在遍历字符串中的所有字符
假设在第i次迭代中,您发现了字符“b”。
您可以计算其基于0的索引
int val=str.charAt(i)-“a”;
对于'b',它是1。即98-97
现在使用左移位运算符,我们找到2^1=>2的值
(1其他答案解释了编码运算符的用法,但我认为它们没有触及此代码背后的逻辑
基本上,代码1 1
0&0->0
1&0->0
因此,checker当前在其相应字符已经出现的位置中有1个,这是if语句中表达式为true的唯一方式
如果字符出现两次,导致1&1->1>0按位移位,其工作原理如下:
示例:a=15(位表示:0000 1111)
对于操作:a似乎我来晚了,但让我试着解释一下
首先,和即操作:
0 & 0 = 0
1 & 0 = 0
0 & 1 = 0
1 & 1 = 1
所以基本上,如果给你一点,你想知道它是1还是0,你只要用1来&它。如果结果是1,那么你有1,否则你有0。我们将使用下面的这个属性
OR即|操作
0 | 0 = 0
1 | 0 = 1
0 | 1 = 1
1 | 1 = 1
所以基本上,如果你得到一点,你想对它做点什么,使输出总是1,那么你就用它做一个| 1
现在,在Java中,int
类型是4个字节,即32位。因此,我们可以使用int
本身作为数据结构,以更简单的方式存储32个状态或布尔值,因为位可以是0或1,即false或true。因为我们假设字符串只由小写字符组成,所以int中有足够的空间来存储e 26个字符中的每一个都有一个布尔值
所以首先我们初始化我们的数据结构,我们调用checker
为0,它只不过是32个零:0000000000000000000000
到目前为止还好吗
现在我们检查字符串,对于每个字符,首先我们得到字符的整数表示
int val = str.charAt(i) - 'a';
我们从中减去a
,因为我们希望整数以0为基础。因此,如果VAL:
a = 0 i.e. `0000000000000000000000`
b = 1 i.e. `0000000000000000000001`
c = 2 i.e. `0000000000000000000010`
d = 4 i.e. `0000000000000000000100`
如上图所示,a是32个零,但其余的字符有一个1和31个零。因此,当我们使用这些字符时,我们将每个字符左移1,即(1我一直在研究该算法,下面是我注意到的也会起作用的内容。当你用手练习时,它使算法更容易理解:
public static boolean isUniqueChars(String str) {
if (str.length() > 26) { // Only 26 characters
return false;
}
int checker = 0;
for (int i = 0; i < str.length(); i++) {
int val = str.charAt(i) - 'a';
int newValue = Math.pow(2, val) // int newValue = 1 << val
if ((checker & newValue) > 0) return false;
checker += newValue // checker |= newValue
}
return true;
public静态布尔值isUniqueChars(String str){
如果(str.length()>26){//仅26个字符
返回false;
}
int-checker=0;
对于(int i=0;i
当我们得到val
(0-25)的值时,我们可以通过val
的值向右移动1,也可以使用2s的幂
此外,只要((checker&newValue)>0)
为false,当我们将旧的checker值和newValue
公共静态布尔值isUniqueChars(String str)相加时,就会生成新的checker值{
public static boolean isUniqueChars(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;
checker |= (1 << val);
}
return true;
}
int-checker=0;
对于(int i=0;i checker |=(1)它与public static boolean isUniqueChars(String str){boolean checker[]=new boolean[str.length())];for(int i=0;i
但标志不是布尔数组,而是以位形式存储在整数变量中。由于此算法使用了布尔数组,因此具有O(n)空间复杂度。使用此位向量可减少空间使用量。简单地说,genius;)+1有帮助!谢谢非常有说明性!谢谢。
if ((checker & (1 << val)) > 0)
return false;
0 | 0 -> 0
0 | 1 -> 1
1 | 0 -> 1
1 | 1 -> 1
check = 0000 0000 0000 0000 0000 1000 1000 0000 |
'b' = 0000 0000 0000 0000 0000 0000 0000 0010
----------------------------------------------
result= 0000 0000 0000 0000 0000 1000 1000 0010
checker |= (1 << val); // checker = checker | (1 << val);
checker = checker | (1 << val)
if ((checker & (1 << val)) > 0)
0 & 0 = 0
1 & 0 = 0
0 & 1 = 0
1 & 1 = 1
0 | 0 = 0
1 | 0 = 1
0 | 1 = 1
1 | 1 = 1
int val = str.charAt(i) - 'a';
a = 0 i.e. `0000000000000000000000`
b = 1 i.e. `0000000000000000000001`
c = 2 i.e. `0000000000000000000010`
d = 4 i.e. `0000000000000000000100`
a = 1 i.e. `0000000000000000000001`
b = 2 i.e. `0000000000000000000010`
c = 4 i.e. `0000000000000000000100`
d = 8 i.e. `0000000000000000001000`
checker = checker | (1 << val);
checker & (1 << val)
public static boolean isUniqueChars(String str) {
if (str.length() > 26) { // Only 26 characters
return false;
}
int checker = 0;
for (int i = 0; i < str.length(); i++) {
int val = str.charAt(i) - 'a';
int newValue = Math.pow(2, val) // int newValue = 1 << val
if ((checker & newValue) > 0) return false;
checker += newValue // checker |= newValue
}
return true;
public static boolean isUniqueChars(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;
checker |= (1 << val);
}
return true;
}