Number 1
Solution 1:
With the n & 1
rightmost determines whether a 1, then continues to determine the right the rightmost one, is repeated until n = 0. The time complexity isO(log2n)
#include <iostream>
using namespace std;
int main() {
int n = 0b1101, cnt = 0;
while (n) {
cnt += n & 1;
n >>= 1;
}
cout << cnt << endl;
return 0;
}
Solution 2:
With n & (n - 1)
erasable rightmost 1 is repeated until n = 0. The time complexity is O(count)
, depending on the number of count 1, this method is better than the first.
#include <iostream>
using namespace std;
int main() {
int n = 0b1101, cnt = 0;
while (n) {
n = n & (n - 1);
++cnt;
}
cout << cnt << endl;
return 0;
}
For determining whether a bit is 1 or 0
Analyzing the k-th position from the right,(n >> (k - 1)) & 1
#include <iostream>
using namespace std;
int main() {
int n = 0b1101;
cout << (n >> 1 & 1) << endl; // 第 2 位为 0
cout << (n >> 2 & 1) << endl; // 第 3 位为 1
return 0;
}
Reversed a bit
Reversal from the right k-th position,n ^ (1 << (k - 1))
#include <iostream>
using namespace std;
int main() {
int n = 0b1101;
cout << (n ^ (1 << 2)) << endl; // 反转第 3 位 -> 1001
cout << (n ^ (1 << 1)) << endl; // 反转第 2 位 -> 1111
return 0;
}
Some practical rules
Bitwise XOR a same number twice ( n ^ x ^ x
), unchanged.
#include <iostream>
using namespace std;
int main() {
int n = 13, x = 666;
cout << (n ^ x ^ x) << endl; // 仍然是 13
return 0;
}
Bitwise with the mold in place, parity determination, more efficient. n & 1
The result is an even number is 0, the result is an odd number is 1.
#include <iostream>
using namespace std;
int main() {
cout << (4 & 1) << endl;
cout << (5 & 1) << endl;
return 0;
}
K k bits to the left take the power of 2, k bits to the right by 2 k-th power. It is common in the divide and conquer strategy, such as merge sort:
#include <cstdlib>
#include <ctime>
#include <iostream>
using namespace std;
void partition(int a[], int l, int m, int r) {
int *t = new int[r - l + 1];
int i = l, j = m + 1, k = 0;
while (i <= m && j <= r) t[k++] = a[i] < a[j] ? a[i++] : a[j++];
while (i <= m) t[k++] = a[i++];
while (j <= r) t[k++] = a[j++];
for (int i = l; i <= r; ++i) a[i] = t[i - l];
delete[] t;
}
void merge_sort(int a[], int l, int r) {
if (l < r) {
int m = (l + r) >> 1; // 相当于 (l + r) / 2
merge_sort(a, l, m);
merge_sort(a, m + 1, r);
partition(a, l, m, r);
}
}
int main() {
srand(time(0));
int a[20];
for (int i = 0; i < 20; ++i) a[i] = rand() % 100;
merge_sort(a, 0, 19);
for (int i = 0; i < 20; ++i) cout << a[i] << " ";
return 0;
}