& | ^在cpp中的用法
& | ^在cpp中的用法:
- 按位与(&)的快捷用法
(1)判断奇偶(替代 %2)
原理:奇数的二进制最低位是 1,偶数是 0,a&1 可提取最低位;
if (x & 1) cout << "奇数"; // 等价于 x%2==1,效率更高
if (!(x & 1)) cout << "偶数";
(2)提取 / 判断某一位是否为 1
原理:1<<i 生成 “第 i 位为 1,其余为 0” 的数,与 a 相与可提取第 i 位;
int a = 10; // 二进制 1010
if (a & (1 << 3)) cout << "第3位是1"; // 1<<3=8,10&8=8≠0 → 输出
(3)快速消除最低位的 1(统计二进制中 1 的个数)
原理:a&(a-1) 会消除 a 二进制中最右侧的 1;
int count_1(int a) {
int cnt = 0;
while (a) {
a &= a-1; // 每次消除一个1
cnt++;
}
return cnt;
}
// 测试:a=6(110)→ 消除1次得4(100),再消除得0 → 返回2
(4)判断是否为 2 的幂
原理:2 的幂的二进制只有 1 个 1,因此 a&(a-1) == 0(且 a≠0);
bool is_power2(int a) {
return a > 0 && (a & (a-1)) == 0;
}
// 测试:a=8(1000)→ 8&7=0 → 返回true;a=6→6&5=4≠0→false
- 按位或(|)的快捷用法
(1)将某一位强制设为 1
原理:1<<i 第 i 位为 1,与 a 相或可将 a 的第 i 位设为 1(其余位不变);
将数字 a 的第 2 位设为 1:
int a = 5; // 101
a |= (1 << 2); // 1<<2=4 → 5|4=5(101),若a=4→4|4=4,a=3→3|4=7(111)
(2)快速生成 “全 1” 掩码
原理:a|(a-1) 可将 a 的二进制从最低位的 1 到末尾全部置为 1;
a=6(110)→ 6|5=7(111),a=8(1000)→8|7=15(1111)。
3. 按位异或(^)的快捷用法
(1)不借助临时变量交换两个数
原理:利用 abb = a 的抵消性;
int a = 3, b = 5;
a ^= b; // a=3^5=6
b ^= a; // b=5^6=3
a ^= b; // a=6^3=5
// 最终 a=5,b=3,完成交换
(2)找数组中 “唯一出现一次的数”
原理:aa=0(相同数抵消),0a=a(最终剩唯一数);
场景:数组中除一个数出现 1 次,其余都出现 2 次(竞赛高频题);
int find_unique(int nums[], int n) {
int res = 0;
for (int i=0; i<n; i++) res ^= nums[i];
return res;
}
// 测试:nums=[1,2,3,2,1] → 01232^1=3 → 返回3
(3)快速翻转某一位(0 变 1,1 变 0)
原理:1<<i 第 i 位为 1,与 a 异或可翻转第 i 位(其余位不变);
翻转 a 的第 1 位:
int a = 5; // 101
a ^= (1 << 1); // 1<<1=2 → 5^2=7(111),再异或一次→5(101)
(4)求两个数的和(不使用 + 号)
原理:a^b 是无进位和,(a&b)<<1 是进位,循环直到进位为 0;
int add(int a, int b) {
while (b) {
int carry = (a & b) << 1; // 计算进位
a = a ^ b; // 无进位和
b = carry; // 进位作为新的b
}
return a;
}
// 测试:add(3,5) → 3^5=6,carry=2 → 6^2=4,carry=4 →4^4=0,carry=8 →0^8=8 → 返回8

浙公网安备 33010602011771号