Bitwise operator in if statement - if-statement

While going through a code i saw this.
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
{
if(i & (1<<j))
{
//code
}
}
}
can anyone how this loop will work?
I know that right part will give be pow(2,j), but i don't understand how will & work here.

It loops over all values from 0 to n, and for each of these:
It loops over each bit in the value. if the value is set:
It executes //code
Lets examine the complex part:
if(i & (1<<j))
1<<j is a common way to set the jth bit (starting from zero). If j==0, then it's 0b00001, if j==3 then it's 0b01000. Then i & <bit> evaluates to <bit> if that bit is set in i, and otherwise it evaluates to 0. So this checks to see if the jth bit is set in i.
The value pairs that trigger the code are these:
i binary js
0 000
1 001 0
2 010 1
3 011 0, 1
4 100 2
5 101 0, 2
6 110 1, 2
etc...
31 11111 0, 1, 2, 3, 4,
Notice how the 1s in the binary mirror the j values for which the code triggers.
Note that if n>=32 then it tries to shift the values too far, and that's undefined behavior. Be sure that doesn't happen.

Related

How many palindromes can you create from array

I'm trying to build a basic code that is taking an int array and outputing all of its optional palindromes.
Example: {1, 2, 2, 2, 3}
Output: {2 2}, {2 1 2}, {2 3 2}, {2 2 2}
I was thinking of reorganizing the array in every way possible and checking if it's an array by each time. But, I think I'm heading to it wrongly.
The code I made for now is:
#include <iostream>
using namespace std;
int main()
{
int arr[] = { 1, 2, 3, 2, 1 };// 7 int //56
bool check = true;
for(int i=0; i< sizeof(arr)/sizeof(int)/2;i++)
{
if(arr[i] != arr[sizeof(arr)/sizeof(int)-1-i])
check = false;
}
if(check)
{
for(int i=0; i< sizeof(arr)/sizeof(int);i++)
{
cout<<arr[i]<< " ";
}
cout<<endl;
}
return 0;
}
I will appreciate help if possible. Thank you all and have an amazing day!
We have to implement 2 major mathematical concepts here
Create a power set
Get all permutations from powerset.
Then, of course check for the palindrome property.
Let's start with the power set.
We will first make a simplification for an easier understanding of the task. We will use lower case letters in this example. Then we will take 4 elements {A,B,C,D} for demo purposes.
What we need to generate is a power set from this. There are 2 main standard approaches.
Counting with checking of set bits via it mask
Setting more and more bits in a field and do permutations.
Let us look at solution 1. Counting. Based on "abcd" we will get
Count Binary Selection (sub set)
DCBA Cardinality
0 0000 {----} 0 Empty set
1 0001 {---A} 1
2 0010 {--B-} 1
3 0011 {--BA} 2
4 0100 {-C--} 1
5 0101 {-C-A} 2
6 0110 {-CB-} 2
7 0111 {-CBA} 3
8 1000 {D---} 4
9 1001 {D--A} 2
10 1010 {D-B-} 2
11 1011 {D-BA} 3
12 1100 {DC--} 3
13 1101 {DC-A} 3
14 1110 {DCB-} 3
15 1111 {DCBA} 4
As a result we will get the powerset:
{{A},{B},{AB},{C},{AC},{BC},{ABC},{D},{AD},{BD},{ABD},{CD},{ACD},{BCD},{ABCD}}
If you look at the output, we see that the elements are not sorted according to their cardinality. Therefore we will choose a different approach. We will set more and more bits in a field an do permutations on them. Also with a selector. Then, we will get something like this:
Binary Selection
0000 {----} Empty set. Ignored
0001 {---A} Set bit 0
0010 {--B-} Permutation
0101 {-C--} Permutation
1000 {D---} Permutation
0011 {--BA} Set next bit number 1
0101 {-C-A} Permutation
1001 {D--A} Permutation
0110 {-CB-} Permutation
1010 {D-B-} Permutation
1100 {D--A} Permutation
0111 {-CBA} Set next bit number 2
1011 {D-BA} Permutation
1101 {DC-A} Permutation
1110 {DCB-} Permutation
1111 {DCBA} Set next bit number 3
As a result we will get the "more reasonable/expected" powerset:
{{A},{B},{C},{D},{AB},{AC},{AD},{BC},{BD},{AD},{ABC},{ABD},{ACD},{BCD},{ABCD}}
By the way. The overall number of sub sets is of course 2^n and the size of the cardinality group is equal to the corresponding binomial coeeficient.
Cardinality
0 4 choose 0 --> 1
1 4 choose 1 --> 4
2 4 choose 1 --> 6
3 4 choose 1 --> 4
4 4 choose 1 --> 1
Sum: 16
The corresponding algorithm is easy to implement, which can also be seen later in the code example.
Next, after having calculated one subset, we will create all permutations of data in this subset with the existing C++ function std::next_permutation.
After a successful check for a Palindrome, we will add this subset to a resulting std::set . We will use the std::set to avoid duplicates.
At the end, we can show the result.
The below example is brute force and hence very very slow for big input arrays.
Anyway, please see the example code below:
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
int main() {
std::vector testData{ 1,2,2,2,3 };
// Here we will store the result
std::set<std::vector<int>> result{};
// Selectors for creating the subsets of the power set
std::vector<bool> selector(testData.size());
// For all number of elements in the original test data
for (size_t k{0}; k < testData.size(); ++k) {
// Set selector bits. In each loop one more bit. So, 1 then 11, then 111 and so on
selector[k] = true;
// Do all permutations of the above set selector bits
do {
// Build the subset
std::vector<int> subset{};
for (std::size_t n{}; n < testData.size(); ++n)
if (selector[n]) subset.push_back(testData[n]);
do {
// Check, if palindrome
if (subset == std::vector<int>(subset.rbegin(), subset.rend()))
result.insert(subset);
} while (std::next_permutation(subset.begin(), subset.end()));
} while (std::prev_permutation(selector.begin(), selector.end()));
}
// Show all resulting palindromes
std::cout << "\n\nNumber of palindromes: " << result.size() << "\n\n";
int counter{ 1 };
for (const std::vector<int>& v : result) {
std::cout << "Palindrome " << counter++ << ":\t";
for (const int i : v) std::cout << ' ' << i;
std::cout << '\n';
}
}

C++ for loop multiple condition inconsistency

Code in question :
#include<iostream>
using namespace std;
int main() {
int a[10] = {0, 1, 0, 1, 0, 1, 1, 0, 0, 1};
for (int i = 0; i < 10; ++i) if (a[i] == 1) cout<<i<<" ";
cout<<endl;
for (int i = 0; i < 10 && a[i] == 1; ++i) cout<<i<<" ";
cout<<endl;
}
Output:
1 3 5 6 9
// and an empty line
If my understanding of condition evaluation is correct, then both the outputs should be the same. As the condition a[i] == 1 is checked each time, i is incremented. So, why is this happening?
I have tested this with g++ and an online ide called ideone link to code.
I believe that I am missing something very basic here and it is a very dumb issue, so please forgive me for asking this in advance.
the condition loop finish in i = 0 because a[0]=0 . your condition to continue is a[i]=1. therefore it finish in first case
The condition in the for loop is evaluated before each iteration, and if it yields false, the loop is exited.
In the first case the condition is i < 10 and this becomes false only after i reaches 10, so the condition in the if is evaluated 10 times and you get the output 1 3 5 6 9.
In the second case the condition is i < 10 && a[i] == 1 which becomes false on the very first iteration when i is 0 as a[0] is 0. The for loop is then terminated and the condition in the if statement is never evaluated and so you do not get any output.
No. The results are not the same. In the first one, the for loop scrolls over 0 to 9 and each time the inner if checks whether the corresponding index of a is equal to 1 or not. So the performance of the first one is clear. The second one acts quite different. The second for holds as long as the condition holds (while it doesn't even hold at the beginning since a[0]=0).
A better example is:
int x[]={1, 1, 1, 0, 0, 0, 0, 0, 1, 1};
the first loop prints out 0 1 2 8 9 and the second one's output is 0 1 2.

Intuition behind working with `k` to find the kth-symbol in the grammar

I took part in a coding contest wherein I encountered the following question:
On the first row, we write a 0. Now in every subsequent row, we look at the previous row and replace each occurrence of 0 with 01, and each occurrence of 1 with 10. Given row N and index K, return the K-th indexed symbol in row N. (The values of K are 1-indexed.)
While solving the question, I solved it like a level-order traversal of a tree, trying to form the new string at each level. Unfortunately, it timed-out. I then tried to think along the terms of caching the results, etc. with no luck.
One of the highly upvoted solutions is like this:
class Solution {
public:
int kthGrammar(int N, int K) {
if (N == 1) return 0;
if (K % 2 == 0) return (kthGrammar(N - 1, K / 2) == 0) ? 1 : 0;
else return (kthGrammar(N - 1, (K + 1) / 2) == 0) ? 0 : 1;
}
};
My question is simple - what is the intuition behind working with the value of K (especially, the parities of K)? (I hope to be able to identify such questions when I encounter them in future).
Thanks.
Look at the sequence recursively. In generating a new row, the first half is identical to the process you used to get the previous row, so that part of the expansion is already done. The second half is merely the same sequence inverted (0 for 1, 1 for 0). This is one classic way to generate a parity map: flip all the bits and append, representing adding a 1 to the start of each binary number. Thinking of expanding the sequence 0-3 to 0-7, we start with
00 => 0
01 => 1
10 => 1
11 => 0
We now replicate the 2-digit sequence twice: first with a leading 0, which preserves the original parity; second with a leading 1, which inverts the parity.
000 => 0
001 => 1
010 => 1
011 => 0
100 => 1
101 => 0
110 => 0
111 => 1
Is that an intuition that works for you?
Just for fun, as a different way to solve this, consider that the nth row (0-indexed) has 2^n elements in it, and a determination as to the value of the kth (0-indexed) element can be made soley according to the parity of how many bits are set in k.
The check for parity in the code you posted is just to make the division by two correct, there's no advanced math or mystery hiding here :) Since the pattern is akin to a tree, where the pattern size multiplies by two for each added row, correctly dividing points to the element's parent. The indexes in this question are said to be "1-indexed;" if the index is 2, dividing by two yields the parent index (1) in the row before; and if the index is 1, dividing (1+1) by two yields that same parent index. I'll leave it to the reader to generalize that to ks parity. After finding the parent, the code follows the rule stated in the question: if the parent is 0, the left-child must be 0 and right-child 1, and vice versa.
0
0 1
0 1 1 0
0 1 1 0 1 0 0 1
0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0
a a b a b b a
0 01 0110 01101001 0110100110010110
a b b a b a a b
0110100110010110 1001011001101001

What is the logic to use bitwise operation in generating subsequences? [duplicate]

This question already has answers here:
What does the statement if (counter & (1<<j)) mean and how does it work?
(2 answers)
Closed last year.
I have an array, A=[1,2,3,4] (where n=4). I want to generate sub-sequences from this array.
Number of subsequences is (2^n -1)
Run from counter 0001 to 1111
for (int counter = 1; counter < 2^n; counter++)
{
for (int j = 0; j < n; j++)
{
Check if the jth bit in the counter is set. If set then print jth element from arr[]
if (counter & (1<<j))
cout << arr[j] << " ";
}
cout << endl;
}
}
can anyone explain me? How it works " counter & (1<
The logic goes like this. Say, like you put in the example, you have n = 4, and, to avoid confusion, let's say the array is A = [5, 7, 8, 9], for example. Then you want all the possible sequences containing some elements (at least one) from the original array. So you want a sequence containing only the first one, a sequence containing the first and the second, the first and the third, etc. Each printed sequence may or may not contain each of the elements in the array. So you could see it as something like this:
| 5 | 7 | 8 | 9 | Sequence
----------------- --------
| 1 | 0 | 0 | 0 | -> 5
| 1 | 1 | 0 | 0 | -> 5 7
| 1 | 0 | 1 | 0 | -> 5 8
...
That is, each sequence can be expressed as a list of bits, each indicating whether each member of the array is included.
In this loop:
for (int counter = 1; counter < 2^n; counter++)
The program iterates from 1 to 2^n - 1, that is 15 in this case. So the values that you get for counter are:
Dec Binary
--- ------
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
10 1010
11 1011
12 1100
13 1101
14 1110
15 1111
If you look closely, you will see that we have all the possible sequences of four elements composed of 0 and 1 in binary (except 0000, which would be the empty sequence and does not interest us). In this loop:
for (int j = 0; j < n; j++)
The program just goes through each bit of counter, from 0 (the rightmost) to n - 1 and whenever it finds a 1 it outputs the corresponding array element. The condition:
if (counter & (1<<j))
Simply computes the number 1<<j which is 1 plus j number of zeros at its right (so, for example, for j = 0 it would be 1 and for j = 2 it would be 100) and then a bitwise and operation, so it basically "filters" the j-th bit only (e.g. 1101 & 100 = 0100), and if the result is not zero then it means there was a one, and so arr[j] must be printed.
Obviously, the problem with the function is that it is limited to the number of bits that the variable counter can hold. That depends on its declared type and your architecture/compiler, but typically it will be either 32 or 64.

C++ using AND operator in integer expression

I'm reading some source code for designing an Octree and found this in the code. I have removed some elements for simplication, but can anyone explain what i&4 is supposed to evaluate to?
for (int i = 0; i < 8; i++)
{
float j = i&4 ? .5f : -.5f;
}
& is the bitwise AND Operator.
It just does a bitwise operation of the value stored in i AND 0x4.
It exactly just isolates the third bit as 2^2 = 4.
Your expression in the loop checks if third bit is set in i and assigns to j (which must be a float!) 0.5 or if not set -0.5
I am not sure, but it may evaluate the bitwise and operation of i and 4 (100), so any number which has a '1' in its third bit will be evaluted to true, otherwise false.
Ex:
5 (101) & 4 (100) = 100 (4) which is different from 0 so its true
8 (1000) & 4 (100) = 0000 (0) which is false
The & operator in this case is a bitwise AND. Since the second operand is 4, a power of 2, it evaluates to 4 when i has its second least-significant bit set, and to 0 otherwise.
The for loop takes i from 0 to 7, inclusive. Consider bit representations of i in this range:
0000 - 0
0001 - 1
0010 - 2
0011 - 3
0100 - 4
0101 - 5
0110 - 6
0111 - 7
^
|
This bit determines the result of i & 4
Therefore, the end result of the conditional is as follows: if the second bit is set (i.e. when i is 4, 5, 6, or 7), the result is 0.5f; otherwise, it is -0.5f.
For the given range of values, this expression can be rewritten as
float j = (i >= 4) ? .5f : -.5f;
i & 4 just evaluate to true when the value-4 bit is set. In your case this only happens in the second half of the loop. So the code could actually be rewritten:
for (int i = 0; i < 4; i++)
{
float j = -.5f;
}
for (int i = 4; i < 8; i++)
{
float j = .5f;
}