我不明白,在环行:我们采取的性格和减去a
,所以“10”? (为什么?)
然后1 << val
:我们通过VAL转移1? (为什么?)
和检查为0,那么我们如何到达> 0
的条件?
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;
}
谢谢
该代码假定str
由小写字母,如果没有重复的字母返回true。 它的工作原理是这样的:
checker
被用作位图,即,在该变量中的每个位被用来保持一个字母的轨道。 减去“A”从字符给出0为“A”,1“B”,2“C”等移1由这个号码放置“一个”,2给出1“B”,4“C “等。
通过O形环( |
)这个值与checker
码跟踪先前遇到的字符。 所以,如果我们遇到第二个“A”例如, checker
有它的第一位集(这是由测试&
if语句),所以我们知道, str
有重复。
总之, checker
被用作布尔的更快和更紧凑的阵列。 这和类似的技术被称为位操作 。
str.charAt(i) - 'a'
返回时,或多或少的“字母表中的字母”:如果str.charAt(i)
是'a'
这是0
,如果是'b'
val
是1
,如果是z
, val
是25
,依此类推。
这样做的其余部分使用位变换技术:如果val
的个位checker
是1
的话,我们已经看到了val
个字符了。 因此, checker & (1 << val)
当且仅当是非零val
个位checker
设置,这意味着我们已经看到了这个角色。 否则,我们设置了val
个位checker
,并继续循环。
现在的问题是很老,但我想我的答案是正确的,清晰的。 我们只有在这种情况下,处理小写字母。 像保罗问, (1 << val)
指移1通过“VAL”不移位“VAL”一个。 因此,例如,“你好”,得到:
1st loop: val = 111 in binary, 7 in decimal
1 << val = 10000000 <-- here one is shifted by 7
checker = 10000000
2nd loop: val = 100 in binary, 4 in decimal
1 << val = 10000
checker = 10010000
3rd loop: val = 1011 in binary, 11 in decimal
1 << val = 100000000000
checker = 100010010000
4th loop: val = 1011 in binary, 11 in decimal
1 << val = 100000000000
(checker & (1 << val)) gives 100000000000 which is greater than 0
The loop is over because 'l' is not unique after 'hel' in 'hello'.
我希望这将清除的东西。 我的源代码,如果你想看看究竟发生了什么。
public class one_one_one {
public static void main(String[] args) {
String chars = "hello";
if (isUniqueChars(chars)) {
System.out.println("Unique");
} else {
System.out.println("Not Unique");
}
}
public static boolean isUniqueChars(String str) {
int checker = 0;
for (int i = 0; i < str.length(); i++) {
int val = str.charAt(i) - 'a';
System.out.println(Integer.toBinaryString(val)); //debug printout
int temp = 1 << val;
System.out.println(Integer.toBinaryString(temp)); //debug printout
System.out.println(checker & (1 << val)); //debug printout
if ((checker & (1 << val)) > 0) {
return false;
}
checker |= (1 << val);
System.out.println(Integer.toBinaryString(checker)); //debug printout
System.out.println(' '); //debug printout
}
return true;
}
}