I am confused about how a bit vector would work to do this (not too familiar with bit vectors). Here is the code given. Could someone please walk me through this?
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;
}
Particularly, what is the checker
doing?
There are couple of excellent answers already provided above. So I don't want to repeat what's everything already said. But did want to add couple of things to help with the above program as I just worked through the same program and had couple of questions but after spending some time, I have more clarity on this program.
First of all "checker" is used to track the character which is already traversed in the String in order to see if there are any characters are getting repeated.
Now "checker" is an int data type so it can only have 32 bits or 4 bytes (depending upon platform) so this program can only work correctly for a character set within a range of 32 characters. That's the reason, this program subtracts 'a' from each character in order to make this program run for only lower case characters. However if you mix lower and upper case characters then it would not work.
By the way, if you do not subtract 'a' from each character (see below statement) then this program will work correctly for only String with upper case characters or String with only lower case characters. So the scope of above program increases from just lower case characters to upper case characters too but they can't be mixed together.
However I wanted to write a generic program using Bitwise Operation which should work for any ASCII characters without worrying about upper case, lower case, numbers or any special character. In order to do this, our "checker" should be large enough to store 256 characters (ASCII Character Set size). But an int in Java would not work as it can only store 32 bits. Hence in below program, I am using BitSet class available in JDK which can have any user defined size passed while instantiating a BitSet object.
Here is a program which does the same thing as above program written using Bitwise operator but this program will work for a String with any character from ASCII character set.
I also assume that your example comes from the book Cracking The Code Interview and my answer is related to this context.
In order to use this algorithm to solve the problem, we have to admit that we only are going to pass characters from a to z (lowercase).
As there is only 26 letters and these are properly sorted in the encoding table we use, this guarantees us that all the potential differences
str.charAt(i) - 'a'
will be inferior to 32 (the size of the int variablechecker
).As explained by Snowbear, we are about to use the
checker
variable as an array of bits. Lets have an approach by example :Let's say
str equals "test"
and so on.. until we find an already set bit in checker for a specific character via the condition
Hope it helps
I think all these answers do explain how this works, however i felt like giving my input on how i saw it better, by renaming some variables, adding some others and adding comments to it:
Simple Explanation (with JS code below)
32-bit
DEC64
for JS.0th
index if we finda
in the string,1st
forb
& so on.Summary of operations:
checker
&index
of the characterInt-32-Arrays
if
the output of the operation was1
output == 1
checker
variable has that particular index-th bit set in both arraysoutput == 0
checker
&index
of the character1
checker
Assumptions:
a
is97
Given below is the JavaScript source code.
Note that in JS, despite integers being of 64 bits, a bit wise operation is always done on 32 bits.
Example: If the string is
aa
then:i = 0
i = 1