⭐算法OJ⭐位操作用法总结+实战指南(C++实现)

news2025/2/26 13:16:06

位操作在OJ 题目中是一种非常高效的工具,常用于优化时间复杂度和空间复杂度。本文是位操作在 OJ 题目中的主要用法总结,并以 C++ 实现为例。

相关题目:《C++⭐算法OJ⭐Single Number 系列(位操作)》

文章目录

  • 1. 基本位操作
    • (1) 与运算 (`&`)
    • (2) 或运算 (`|`)
    • (3) 异或运算 (`^`)
    • (4) 取反运算 (`~`)
    • (5) 左移 (`<<`) 和右移 (`>>`)
  • 2. 常见应用场景
    • (1) 判断奇偶性
    • (2) 交换两个数
    • (3) 统计二进制中 1 的个数
    • (4) 判断一个数是否是 2 的幂
    • (5) 找到最低位的 1
    • (6) 快速乘除 2 的幂
  • 3. 高级应用
    • (1) 状态压缩
    • (2) 枚举子集
    • (3) 快速幂算法
    • (4) 查找只出现一次的数字
    • (5) 查找两个只出现一次的数字
  • 4. 总结

1. 基本位操作

(1) 与运算 (&)

用于提取某些二进制位。

示例:提取最低 4 位:

int num = 0b11011010;
int lower4 = num & 0b1111; // 结果为 0b1010

(2) 或运算 (|)

用于设置某些二进制位。

示例:设置第 3 位为 1:

int num = 0b11011010;
num = num | (1 << 2); // 结果为 0b11011110

(3) 异或运算 (^)

用于翻转某些二进制位。

示例:翻转第 4 位:

Copy
int num = 0b11011010;
num = num ^ (1 << 3); // 结果为 0b11010010

(4) 取反运算 (~)

用于翻转所有二进制位。

示例:

int num = 0b11011010;
num = ~num; // 结果为 0b00100101(假设 int 为 8 位)

(5) 左移 (<<) 和右移 (>>)

左移:将二进制位向左移动,低位补 0。

右移:将二进制位向右移动,高位补 0(逻辑右移)或补符号位(算术右移)。

示例:

int num = 0b11011010;
int leftShifted = num << 2; // 结果为 0b1101101000
int rightShifted = num >> 2; // 结果为 0b00110110

2. 常见应用场景

(1) 判断奇偶性

利用最低位是否为 1 来判断奇偶性。

示例:

bool isOdd(int num) {
    return num & 1; // 如果结果为 1,则是奇数
}

(2) 交换两个数

利用异或运算交换两个数,无需额外空间。

示例:

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

(3) 统计二进制中 1 的个数

利用 n & (n - 1) 每次消除最低位的 1。

示例:

int countOnes(int num) {
    int count = 0;
    while (num) {
        num = num & (num - 1); // 消除最低位的 1
        count++;
    }
    return count;
}

(4) 判断一个数是否是 2 的幂

2 的幂的二进制表示中只有一个 1。

示例:

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

(5) 找到最低位的 1

利用 n & -n 可以找到最低位的 1。

示例:

int lowestBit(int num) {
    return num & -num;
}

(6) 快速乘除 2 的幂

左移 1 位相当于乘以 2,右移 1 位相当于除以 2。

示例:

int multiplyByTwo(int num) {
    return num << 1;
}
int divideByTwo(int num) {
    return num >> 1;
}

3. 高级应用

(1) 状态压缩

利用二进制位表示状态,常用于动态规划或回溯算法。

示例:表示集合的子集:

int subset = 0b1010; // 表示集合 {1, 3}

(2) 枚举子集

利用位运算枚举集合的所有子集。

示例:

void enumerateSubsets(int set) {
    for (int subset = set; subset; subset = (subset - 1) & set) {
        // 处理子集
    }
}

(3) 快速幂算法

利用位运算加速幂运算。

示例:

int fastPow(int base, int exponent) {
    int result = 1;
    while (exponent) {
        if (exponent & 1) result *= base;
        base *= base;
        exponent >>= 1;
    }
    return result;
}

(4) 查找只出现一次的数字

利用异或运算找出数组中只出现一次的数字。

示例:

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

(5) 查找两个只出现一次的数字

利用异或运算和分组思想。

示例:

vector<int> singleNumber(vector<int>& nums) {
    int xorResult = 0;
    for (int num : nums) xorResult ^= num;
    int mask = 1;
    while ((xorResult & mask) == 0) mask <<= 1;
    int num1 = 0, num2 = 0;
    for (int num : nums) {
        if (num & mask) num1 ^= num;
        else num2 ^= num;
    }
    return {num1, num2};
}

4. 总结

位操作在 OJ 题目中的主要用途包括:

  • 高效计算:如快速幂、统计 1 的个数。

  • 状态表示:如状态压缩、枚举子集。

  • 优化空间:如交换两个数、判断奇偶性。

  • 解决特定问题:如查找只出现一次的数字。

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

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

相关文章

Bugku CTF CRYPTO

Bugku CTF CRYPTO 文章目录 Bugku CTF CRYPTO聪明的小羊ok[-<>]散乱的密文.!? 聪明的小羊 描 述: 一只小羊翻过了2个栅栏 fa{fe13f590lg6d46d0d0} 分 析&#xff1a;栅栏密码&#xff0c;分2栏&#xff0c;一个栏里有11个 ①手动解密 f a { f e 1 3 f 5 9 0 l g 6 d 4 …

【洛谷】【ARC100E】Or Plus Max(高维前缀和)

传送门&#xff1a;Or Plus Max 高维前缀和 题目描述 長さ 2N の整数列 A0​, A1​, ..., A2N−1​ があります。&#xff08;添字が 0 から始まることに注意&#xff09; 1 ≤ K ≤ 2N−1 を満たすすべての整数 K について、次の問題を解いてください。 i,j を整数と…

SmolLM2:多阶段训练策略优化和高质量数据集,小型语言模型同样可以实现卓越的性能表现

SmolLM2 采用创新的四阶段训练策略&#xff0c;在仅使用 1.7B 参数的情况下&#xff0c;成功挑战了大型语言模型的性能边界&#xff1a; 在 MMLU-Pro 等测试中超越 Qwen2.5-1.5B 近 6 个百分点数学推理能力&#xff08;GSM8K、MATH&#xff09;优于 Llama3.2-1B在代码生成和文…

《Effective Objective-C》阅读笔记(中)

目录 接口与API设计 用前缀避免命名空间冲突 提供“全能初始化方法” 实现description方法 尽量使用不可变对象 使用清晰而协调的命名方式 方法命名 ​编辑类与协议命名 为私有方法名加前缀 理解OC错误模型 理解NSCopying协议 协议与分类 通过委托与数据源协议进行…

Hbase客户端API——语句大全

目录 创建表&#xff1a; 插入数据&#xff1a; 删除数据&#xff1a; 修改数据&#xff1a; 查询数据&#xff1a;Get 查询数据&#xff1a;Scan 查询数据&#xff1a;过滤查询 创建表&#xff1a; 检验&#xff1a; 插入数据&#xff1a; 验证 一次多条数据插入 验证&…

MQ(Message Queue)

目录 MQ(Message Queue)基本概念 为什么要使用消息队列&#xff1f; 使用消息队列有什么缺点&#xff1f; 如何保证消息不丢失?(如何保证消息的可靠性传输?/如何处理消息丢失的问题?) 通用的MQ场景&#xff1a; RabbitMQ如何保证消息不丢失&#xff1f; 生产者丢数据…

计算机网络————(三)

前文二 前文一 Websocket协议 是一种存在TCP协议之上的协议 当客户端需要了解服务器是否更新就需要不断给客户端发送请求询问是否更新&#xff0c;这行会造成服务端压力很大 而Websocket相当于服务器一旦更新了就会给客户端发送消息表明自己更新了&#xff0c;类似客户端订阅…

【音视频】音视频录制、播放原理

一、音视频录制原理 通常&#xff0c;音视频录制的步骤如下图所示&#xff1a; 我们分别从音频和视频开始采样&#xff0c;通过麦克风和摄像头来接受我们的音频信息和图像信息&#xff0c;这通常是同时进行的&#xff0c;不过&#xff0c;通常视频的采集会比音频的采集慢&…

deepseek 导出导入模型(docker)

前言 实现导出导入deepseek 模型。deepseek 安装docker下参考 docker 导出模型 实际生产环境建议使用docker-compose.yml进行布局&#xff0c;然后持久化ollama模型数据到本地参考 echo "start ollama" docker start ollama#压缩容器内文件夹&#xff0c;然后拷贝…

基于Redis 的分布式 session 图解

Redis 分布式 Session 工作原理 1. 传统 Session 的问题 在传统单服务器环境中&#xff0c;HTTP Session 存储在应用服务器的内存中。这在分布式系统中会导致问题&#xff1a; 用户的请求可能被分发到不同服务器&#xff0c;导致会话不一致服务器宕机会导致会话丢失需要依赖…

DeepSeek-R1本地部署保姆级教程

一、DeepSeek-R1本地部署配置要求 &#xff08;一&#xff09;轻量级模型 ▌DeepSeek-R1-1.5B 内存容量&#xff1a;≥8GB 显卡需求&#xff1a;支持CPU推理&#xff08;无需独立GPU&#xff09; 适用场景&#xff1a;本地环境验证测试/Ollama集成调试 &#xff08;二&a…

【deepseek】本地部署+webui访问

背景 最近deepseek很火&#xff0c;但是官网的老是被限流使用&#xff0c;还有就是自己也想着玩一玩&#xff0c;于是准备在自己电脑跑一个 直接附上结果地址mydeepseek 准备工作 windows和linux都可 我这里选择linux&#xff0c;ubuntu系统 安装ollama 看下图&#xff0…

博客系统笔记总结 2( Linux 相关)

Linux 基本使用和程序部署 基本命令 文件操作 显示当前目录下的文件 ls&#xff1a;显示当前目录下的文件 ll&#xff1a;以列表的形式展示&#xff0c;包括隐藏文件 进入目录 && 显示当前路径 cd&#xff1a;进入目录&#xff08;后面跟相对路径或者绝对路径&…

Flutter - 基础Widget

Flutter 中万物皆 Widget&#xff0c;基础Widget 同步对应 Android View. 普通文本 Text /*** 控制文本样式统一使用 style:TextStyle, 例&#xff1a;fontSize(字体大小),color(颜色),shadows(阴影)等等* 控制文本布局需单独设置&#xff1a;* textAlign(文不对齐方式)* te…

如何在 Linux 上安装和配置 Zsh

文章目录 如何在 Linux 上安装和配置 Zsh1. 安装 Zsh1.1 在 Ubuntu/Debian 上安装1.2 在 CentOS/RHEL/Fedora 上安装1.3 在 Arch Linux 上安装1.4 验证 Zsh 安装 2. 设置 Zsh 为默认 Shell2.1 验证默认 shell 3. 配置 Zsh3.1 使用 Oh My Zsh3.1.1 安装 Oh My Zsh3.1.2 启用插件…

【System Verilog and UVM基础入门26】Verdi使用教程指南

《Verdi使用教程指南 》 下载链接&#xff1a; https://download.csdn.net/download/TommiWei/90429701https://download.csdn.net/download/TommiWei/90429701 朋友你好&#xff0c;不管你是否使用过Verdi这款EDA仿真工具。 不管你是否还在寻找免费的使用教材。 不管你是否…

3dtiles平移旋转工具制作

3dtiles平移旋转缩放原理及可视化工具实现 背景 平时工作中&#xff0c;通过cesium平台来搭建一个演示场景是很常见的事情。一般来说&#xff0c;演示场景不需要多完善的功能&#xff0c;但是需要一批三维模型搭建&#xff0c;如厂房、电力设备、园区等。在实际搭建过程中&…

【STL专题】优先级队列priority_queue的使用和模拟实现,巧妙利用仿函数解决优先级

欢迎来到 CILMY23的博客 &#x1f3c6;本篇主题为&#xff1a;优先级队列priority_queue的使用和模拟实现&#xff0c;巧妙利用仿函数解决优先级 &#x1f3c6;个人主页&#xff1a;CILMY23-CSDN博客 &#x1f3c6;系列专栏&#xff1a; C | C语言 | 数据结构与算法 | Linux…

数据开发面试:DQL,

DQL常见面试题 where 和 having 的区别 三个排序开窗函数的区别 left join 用where 筛选 和 用on筛选的区别 ON 子句&#xff1a;用于定义连接条件&#xff0c;不会丢失左表的行。 WHERE 子句&#xff1a;用于过滤连接后的结果集&#xff0c;可能会丢失左表中没有匹配的行 …

最长递增子序列(贪心算法)思路+源码

文章目录 题目[](https://leetcode.cn/problems/longest-increasing-subsequence/)算法原理源码总结题目 首先,要掌握动态规划加二分查找 算法原理 1.回顾dp的解法 状态表示:dp[i]表示:以i位置的元素为结尾的所有的子序列中,最长递增子序列的长度 状态转移方程:dp[i]= m…