Topics
Bitmasking is a powerful technique for generating all possible subsequences (aka a power set) of a given set or string. Each subsequence can be represented by a binary number (mask), where each bit indicates whether to include a particular element in the subsequence.
Given a set of size n
, we can represent all possible subsequences using integers from 0
to 2^n - 1
. Each integer corresponds to a bitmask, where the i-th
bit is 1
if the i-th
element is included in the subsequence, and 0
otherwise.
Steps to Generate Subsequences
- Loop through all integers from
0
to2^n - 1
- For each integer (bitmask), check each bit:
- If the
i-th
bit is set, include thei-th
element in the current subsequence
- If the
- Store or print the generated subsequence
Example Code
void generateSubsequences(const string &str) {
int n = str.length();
int totalSubsequences = 1 << n; // 2^n
for (int mask = 0; mask < totalSubsequences; ++mask) {
string subsequence;
for (int i = 0; i < n; ++i) {
// Check if the i-th bit is set
if (mask & (1 << i)) {
subsequence += str[i];
}
}
cout << subsequence << endl; // Print the current subsequence
}
}
- Time Complexity: The time complexity of this approach is , where is the number of subsequences and is the length of the string. This is because for each of the masks, we may need to check up to bits
- Space Complexity: The space complexity is for storing the current subsequence being generated