int leftOne(unsigned int val) {
if (0 == val) {
return -1;
}
return __builtin_ffs(val) - 1;
}
int rightOne(unsigned int val) {
if (0 == val) {
return -1;
}
return (int)sizeof(val) * 8 - 1 - __builtin_clz(val);
}
auto nextValueIndex = [](unsigned int val, function<int(int)> func) {
return [value = val, func = std::move(func)]() mutable {
int v = func(value);
if (v == -1) {
return -1;
}
value ^= (1 << v);
return v;
};
};
vector<int> nextValueVec(unsigned int val, function<int(int)> func) {
vector<int> ans;
auto gen = nextValueIndex(val, std::move(func));
int p;
while ((p = gen()) != -1) {
if (p == -1) {
break;
}
ans.push_back(p);
}
return ans;
}
int main() {
for (int i = 0; i <= 100000000; i++) {
auto left = nextValueVec(i, leftOne);
auto right = nextValueVec(i, rightOne);
int la = 0;
for (auto k : left) {
la |= (1 << k);
}
int ra = 0;
for (auto k : left) {
ra |= (1 << k);
}
if (i == la && la == ra) {
} else {
cout << i << "\t" << la << "\t" << ra << endl;
}
}
}
位运算在很多时候可以发挥出强大的威力, 尤其在需要状态压缩的算法题里面
// 位操作合集
// 最左的 1 的位置
int leftOneIndex(unsigned int val) {
if (val == 0) {
return -1;
}
return 31 - __builtin_clz(val);
}
// 最右1的位置
int rightOneIndex(unsigned int val) {
if (val == 0) {
return -1;
}
return __builtin_ffs(val) - 1;
}
// 二进制1的个数
int oneCount(unsigned int val) {
return __builtin_popcount(val);
}
int countOne(int val) {
cout << bitset<32>(val) << endl;
val = countOneHelper(val, 1, 0x55555555);
cout << bitset<32>(val) << endl;
val = countOneHelper(val, 2, 0x33333333);
cout << bitset<32>(val) << endl;
val = countOneHelper(val, 4, 0x0f0f0f0f);
cout << bitset<32>(val) << endl;
val = countOneHelper(val, 8, 0x00ff00ff);
cout << bitset<32>(val) << endl;
val = countOneHelper(val, 16, 0x0000ffff);
cout << bitset<32>(val) << endl;
return val;
}
using func = function<int()>;
// 下一个1的位置, 从低位开始到高位
auto nextRightOneIndex(unsigned int val) -> func {
return [value = val]() mutable -> int {
int p = rightOneIndex(value);
if (p != -1) {
value ^= (1 << p);
}
return p;
};
}
int main() {
auto v = nextRightOneIndex(7);
int p;
while ((p = v()) != -1) {
cout << p << endl;
}
}
位操作
1. 得到最右 1
a & (-a)
或者 a & (~(a - 1))
-a = ~(a - 1)
2. 得到 1的个数
a & (a - 1) 的次数
3 对于负数 (a - 1) ^ -1 = abs(a)
绝对值
int abs(int x) {
int y = x >> 31;
return (x - 1) ^ y;
}
4. x 为负数则
~(x - 1) = (x - 1) ^ (-1)
位运算在很多时候可以发挥出强大的威力, 尤其在需要状态压缩的算法题里面
位运算在很多时候可以发挥出强大的威力, 尤其在需要状态压缩的算法题里面
位运算在很多时候可以发挥出强大的威力, 尤其在需要状态压缩的算法题里面
位运算在很多时候可以发挥出强大的威力, 尤其在需要状态压缩的算法题里面
位运算在很多时候可以发挥出强大的威力, 尤其在需要状态压缩的算法题里面
位运算在很多时候可以发挥出强大的威力, 尤其在需要状态压缩的算法题里面
位运算在很多时候可以发挥出强大的威力, 尤其在需要状态压缩的算法题里面
位运算在很多时候可以发挥出强大的威力, 尤其在需要状态压缩的算法题里面
位运算在很多时候可以发挥出强大的威力, 尤其在需要状态压缩的算法题里面
位运算在很多时候可以发挥出强大的威力, 尤其在需要状态压缩的算法题里面