Bit Set Class
Problem
Write a class BitSet that stores up to 1024 yes/no flags (index 0 to 1023) in the bits of 32-bit numbers. It offers set(i), clear(i), flip(i), get(i) and count(). Every input line is a command: SET i, CLEAR i, FLIP i, GET i or COUNT. SET, CLEAR and FLIP print ok. GET prints 1 or 0. COUNT prints how many flags are on.
Constraints
- 1 <= lines <= 10^4
- 0 <= i <= 1023
Examples
Input
SET 3 GET 3 FLIP 3 GET 3 COUNT
Output
ok 1 ok 0 0
Solutions
A flag needs one bit, not one byte. The class hides the word and mask arithmetic behind five small methods, so callers only think in flag numbers. 1024 flags use 128 bytes.
/*
* Problem : Process lines.
* Input : Several command lines.
* Output : One result per command.
* Approach: Bits in 32-bit words.
* Time : O(n)
* Space : O(1)
* Java : 8 or newer.
*/
import java.util.Scanner;
public class Main {
// Step 1: 1024 flags need 32 words of 32 bits. Flag i lives in word i / 32 at bit i % 32.
static class BitSet {
private final int[] words = new int[32];
void set(int i) {
words[i >> 5] |= 1 << (i & 31);
}
void clear(int i) {
words[i >> 5] &= ~(1 << (i & 31));
}
// Step 2: XOR with the mask turns the bit over: on becomes off and off becomes on.
void flip(int i) {
words[i >> 5] ^= 1 << (i & 31);
}
int get(int i) {
return (words[i >> 5] >>> (i & 31)) & 1;
}
int count() {
int total = 0;
for (int word : words) {
total += Integer.bitCount(word);
}
return total;
}
}
// This method solves the task. It receives the input and returns the answer.
static String[] solve(String[] lines) {
BitSet bits = new BitSet();
String[] output = new String[lines.length];
for (int i = 0; i < lines.length; i++) {
String[] part = lines[i].split(" ");
if (part[0].equals("COUNT")) {
output[i] = String.valueOf(bits.count());
} else if (part[0].equals("GET")) {
output[i] = String.valueOf(bits.get(Integer.parseInt(part[1])));
} else {
int index = Integer.parseInt(part[1]);
if (part[0].equals("SET")) {
bits.set(index);
} else if (part[0].equals("CLEAR")) {
bits.clear(index);
} else {
bits.flip(index);
}
output[i] = "ok";
}
}
return output;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
java.util.List<String> all = new java.util.ArrayList<>();
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (!line.isEmpty()) {
all.add(line);
}
}
String[] lines = all.toArray(new String[0]);
System.out.println(String.join("\n", solve(lines)));
}
}
Hints (2)
- Which word and which bit hold flag 70?
- What does XOR do to a bit?