C++位运算精要:高效解题的利器

news2025/4/2 21:30:03

引言

在算法竞赛和底层开发中,位运算(Bit Manipulation)因其极高的执行效率而广受青睐。它能在O(1)时间复杂度内完成某些复杂操作,大幅优化程序性能。本文系统梳理C++位运算的核心技巧,涵盖基础操作、经典应用、优化策略及实战例题,帮助读者掌握这一高效工具。


一、位运算基础

1. 六大基本操作

运算符名称示例(二进制)说明
&按位与1010 & 1100 = 1000同1为1,否则为0
|按位或1010|1100 = 1110有1则1,全0为0
^按位异或1010 ^ 1100 = 0110不同为1,相同为0
~按位取反~1010 = 0101(4位)0变1,1变0
<<左移0011 << 2 = 1100低位补0,相当于×2ⁿ
>>右移1100 >> 2 = 0011高位补符号位(算术右移)

2. 常用位运算性质

  • 异或(XOR)特性

    • a ^ a = 0a ^ 0 = a

    • 交换律:a ^ b = b ^ a

    • 结合律:(a ^ b) ^ c = a ^ (b ^ c)

  • 与(AND)和或(OR)的分配律

    • a & (b | c) = (a & b) | (a & c)

    • a | (b & c) = (a | b) & (a | c)


二、位运算实战技巧

1. 判断奇偶

bool isOdd(int n) {
    return n & 1; // 奇数返回true
}

原理:二进制末位为1表示奇数。

2. 交换两个数(无需临时变量)

void swap(int &a, int &b) {
    a ^= b;
    b ^= a;
    a ^= b;
}

注意:若ab指向同一内存,此方法会失效。

3. 取绝对值

int abs(int n) {
    int mask = n >> (sizeof(int) * 8 - 1); // 符号位扩展
    return (n ^ mask) - mask;
}

适用场景:嵌入式设备等无分支优化需求。

4. 检查是否为2的幂

bool isPowerOfTwo(int n) {
    return n > 0 && (n & (n - 1)) == 0;
}

原理:2ⁿ的二进制形式为100...0n & (n-1)会消除唯一的1。

5. 统计二进制中1的个数(Brian Kernighan算法)

int countOnes(int n) {
    int count = 0;
    while (n) {
        n &= (n - 1); // 每次消除最右边的1
        count++;
    }
    return count;
}

时间复杂度:O(k),k为1的个数。

6. 最低位的1

int lowBit(int x) {
    return x & (-x);
}

应用:树状数组(Fenwick Tree)的核心操作。

7. 模拟集合操作

  • 表示集合:用整数二进制位表示元素是否存在(如mask = 5101)表示包含第0和第2个元素)。

  • 常用操作

    int S = 0b1010;          // 集合{1, 3}
    S |= (1 << 2);           // 添加元素2 → S = 0b1110
    S &= ~(1 << 1);          // 删除元素1 → S = 0b1100
    bool has = S & (1 << 3); // 检查元素3是否存在

三、位运算优化策略

1. 替代乘除法

  • 左移1位等价于×2:

    int a = 5;
    a <<= 1; // a = 10
  • 右移1位等价于÷2(向下取整):

    int b = 7;
    b >>= 1; // b = 3

2. 状态压缩DP

问题示例:旅行商问题(TSP)中,用二进制数表示访问过的城市。

int dp[1 << n][n]; // dp[mask][i]表示从城市i出发,访问过mask集合的最短路径
for (int mask = 0; mask < (1 << n); mask++) {
    for (int i = 0; i < n; i++) {
        if (mask & (1 << i)) {
            // 状态转移
        }
    }
}

3. 快速幂算法

int fastPow(int a, int b) {
    int res = 1;
    while (b) {
        if (b & 1) res *= a;
        a *= a;
        b >>= 1;
    }
    return res;
}

时间复杂度:O(log b)。


四、经典例题解析

例题1:只出现一次的数字(LeetCode 136)

问题:数组中只有一个数出现一次,其余均出现两次,找出该数。
解法

int singleNumber(vector<int>& nums) {
    int res = 0;
    for (int num : nums) res ^= num;
    return res;
}

关键点:利用a ^ a = 0的性质。

例题2:位1的个数(LeetCode 191)

问题:统计无符号整数的二进制表示中1的个数。
解法

int hammingWeight(uint32_t n) {
    int count = 0;
    while (n) {
        n &= (n - 1);
        count++;
    }
    return count;
}

例题3:子集生成(LeetCode 78)

问题:给定无重复元素的数组,返回所有子集。
位运算解法

vector<vector<int>> subsets(vector<int>& nums) {
    int n = nums.size();
    vector<vector<int>> res;
    for (int mask = 0; mask < (1 << n); mask++) {
        vector<int> subset;
        for (int i = 0; i < n; i++) {
            if (mask & (1 << i)) subset.push_back(nums[i]);
        }
        res.push_back(subset);
    }
    return res;
}

五、总结

位运算通过直接操作二进制位,能够实现:

  1. 高效数学运算(如乘除、取模);

  2. 状态压缩(优化DP、集合操作);

  3. 算法优化(快速幂、Brian Kernighan算法)。

掌握位运算,不仅能提升代码性能,还能在面试和竞赛中脱颖而出。建议通过LeetCode相关题目(如268371201)加强练习。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2325977.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

开源的CMS建站系统可以随便用吗?有什么需要注意的?

开源CMS建站系统虽然具有许多优点&#xff0c;但并非完全“随便用”。无论选哪个CMS系统&#xff0c;大家在使用的时候&#xff0c;可以尽可能地多注意以下几点&#xff1a; 1、版权问题 了解开源许可证&#xff1a;不同的开源CMS系统采用不同的开源许可证&#xff0c;如GPL、…

初始ARM

ARM最基础的组成单元。 最小系统&#xff1a;能系统能够正常工作的最少器件构成的系统 。 一、CPU基础定义 1. 核心定位 计算机三大核心部件&#xff1a; CPU&#xff08;运算与控制&#xff09;内部存储器&#xff08;数据存储&#xff09;输入/输出设备&#xff08;数据交互…

DataPlatter:利用最少成本数据提升机器人操控的泛化能力

25年3月来自中科院计算所的论文“DataPlatter: Boosting Robotic Manipulation Generalization with Minimal Costly Data”。 视觉-语言-动作 (VLA) 模型在具身人工智能中的应用日益广泛&#xff0c;这加剧对多样化操作演示的需求。然而&#xff0c;数据收集的高成本往往导致…

诠视科技MR眼镜如何安装apk应用

诠视科技MR眼镜如何安装apk应用 1、使用adb工具安装1.1 adb工具下载1.2 解压adb文件1.3 使用adb安装apk1.4 常用adb命令 2、拷贝到文件夹安装 1、使用adb工具安装 1.1 adb工具下载 点击下面的链接开始下载adb工具&#xff0c;下载结束以后解压文件。 下载链接: https://down…

搭建前端环境和后端环境

搭建前端环境 ①、安装vscode&#xff0c;并安装相应的插件工具 ②、安装node.js&#xff0c;可以选择当前版本&#xff0c;或者其他版本 ③、创建工作区 创建一个空文件夹&#xff0c;然后通过vscode工具打开&#xff0c;保存为后缀名为.code-workspace ④、从gitee…

Polhemus FastScan 单摄像头3D激光扫描器

FastSCAN Cobra是Polhemus公司研制的手持激光扫描仪。与以前的产品比较&#xff0c;它节省了30&#xff05;的费用&#xff0c;体积也减小了一半 &#xff0c;但仍然保留了所有功能&#xff0c;使用和携带都更加方便。作为超小的手持激光扫描仪,FastSCAN Cobra对扫描三维物体具…

召唤数学精灵

1.召唤数学精灵 - 蓝桥云课 问题描述 数学家们发现了两种用于召唤强大的数学精灵的仪式&#xff0c;这两种仪式分别被称为累加法仪式 A(n) 和累乘法仪式 B(n)。 累加法仪式 A(n) 是将从1到 n 的所有数字进行累加求和&#xff0c;即&#xff1a; A(n)12⋯n 累乘法仪式 B(n) …

2025图像处理和深度学习国际学术会议(IPDL 2025)

重要信息 官网&#xff1a;www.IPDL.xyz 时间&#xff1a;2025年4月11-13日 地点&#xff1a;中国-成都 简介 随着深度学习和图像处理技术的迅速发展&#xff0c;相关技术的应用逐渐渗透到各个行业&#xff0c;如医疗影像分析、自动驾驶、安防监控和智能制造等。这些应用的…

使用uni-app框架 写电商商城前端h5静态网站模板项目-手机端-前端项目练习

以前用vue2 分享过一个电商商城前端静态网站项目-电脑端&#xff0c;需要的小伙伴还是很多的&#xff0c;最近又花了几天更新了一个 手机端的 电商商城h5项目&#xff0c;今天也分享一下实现方案。 对于以前写的 电商商城前端静态网站模板-电脑端&#xff0c;有兴趣的小伙伴 可…

远心镜头原理

文章目录 原理特点分类应用领域 参考&#xff1a;B站优致谱视觉 原理 远心镜头的工作原理基于其特殊的光学设计&#xff0c;旨在解决普通镜头存在的视差问题。它通过将镜头的光轴与成像面垂直&#xff0c;并使主光线平行于光轴&#xff0c;从而确保在一定的物距范围内&#xf…

centos7修复漏洞CVE-2023-38408

漏洞描述&#xff1a; CVE-2023-38408 是 OpenSSH 组件中的一个远程代码执行&#xff08;RCE&#xff09;漏洞&#xff0c;影响 OpenSSH 代理&#xff08;ssh-agent&#xff09;的安全性。该漏洞被发现于 2023 年 7 月&#xff0c;并被标记为 高危&#xff08;CVSS 评分 7.3&a…

uniapp微信小程序封装navbar组件

一、 最终效果 二、实现了功能 1、nav左侧返回icon支持自定义点击返回事件&#xff08;默认返回上一步&#xff09; 2、nav左侧支持既显示返回又显示返回首页icon 3、nav左侧只显示返回icon 4、nav左侧只显示返回首页icon 5、nav左侧自定义left插槽 6、nav中间支持title命名 7…

系统思考与心智模式

我们的生命为什么越来越长&#xff1f;因为有了疫苗&#xff0c;有了药物。可这些是怎么来的&#xff1f;是因为我们发现了细菌的存在。但在很久以前&#xff0c;医生、助产士甚至都不洗手——不是他们不负责&#xff0c;而是根本不知道“细菌”这回事。那细菌是怎么被发现的&a…

数据库--数据库设计

目录&#xff1a; 1.数据库设计和数据模型 2.概念结构设计&#xff1a;E-R模型 3.逻辑结构设计&#xff1a;从E-R图到关系设计 4.数据库规范化设计理论 5.数据库规范化设计实现 1.数据库设计和数据模型 数据库设计会影响数据库自身和上层应用的性能。 一个好的数据库设计可以提…

[Mac]利用hexo-theme-fluid美化个人博客

接上文,使用Fluid美化个人博客 文章目录 一、安装hexo-theme-fluid安装依赖指定主题创建「关于页」效果展示 二、修改个性化配置1. 修改网站设置2.修改文章路径显示3.体验分类和标签4.左上角博客名称修改5.修改背景图片6.修改关于界面 欢迎大家参观 一、安装hexo-theme-fluid 参…

黑盒测试的场景法(能对项目业务进行设计测试点)

定义: 通过运用场景来对系统的功能点或业务流程的描述&#xff0c;设计用例遍历场景&#xff0c;验证软件系统功能的正确性从而提高测试效果的一种方法。 场景法一般包含基本流和备用流。 基本流:软件功能的正确流程&#xff0c;通常一个业务只存在一个基本流且基本流有一个…

通过Anaconda Prompt激活某个虚拟环境并安装第三方库

打开 Anaconda Prompt 在Windows中&#xff0c;可以通过开始菜单搜索 Anaconda Prompt 来打开。&#xff08;红色箭头指向的地方。&#xff09; 激活虚拟环境 输入以下命令来激活您的虚拟环境&#xff08;假设虚拟环境名称为 myenv&#xff09;&#xff1a; conda activate…

全长约8.3公里!宁波象山港跨海大桥南中塔柱云端合龙

快科技3月31日消息&#xff0c;据报道&#xff0c;由中国交建二航局承建的宁波象山港跨海大桥顺利完成南中塔柱合龙施工&#xff0c;标志着这一重大交通工程取得阶段性突破。 这座连接宁波鄞州区与象山县的跨海通道全长8.3公里&#xff0c;其标志性的南主塔采用创新"钻石…

使用 2 端口探头测量 40 uOhm(2000 安培)PDN 的挑战 – 需要多少 CMRR?

部分 1 / 3 本文是 3 部分系列的第一部分&#xff1a; 第 2 部分 - 测量结果&#xff01; 第 3 部分 - 使用另一台 VNA 的测量结果 介绍 我们大多数人都知道 2 端口测量中的接地回路。我们大多数人也都知道&#xff0c;我们需要引入接地回路隔离器来纠正错误。如果没有&…

蓝桥杯——统计子矩阵

解法&#xff1a;二维前缀和双指针 代码&#xff1a; #include <iostream> using namespace std; typedef long long ll; ll prefix[505][505], a[250010]; int main() {ll n, m, k, ans 0; cin >> n >> m >> k;for(int i 1; i < n; i)for(int …