博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
位运算--妙用大集合
阅读量:3926 次
发布时间:2019-05-23

本文共 3436 字,大约阅读时间需要 11 分钟。

微信搜索:编程笔记本

微信搜索:编程笔记本
微信搜索:编程笔记本

今天要给大家分享的是位运算的几种妙用。

位运算大多时候都很晦涩难解,大家若是对某种用途的原理不理解,请私信告诉我,我将给予详细解答。

目录

文章目录

1. 位运算符

&按位与

|按位或
^异或
~取反
<<左移(右边补零)
>>右移(左边补符号位)

微信搜索:编程笔记本

微信搜索:编程笔记本
微信搜索:编程笔记本

2. 交换两个变量的值

常规操作:

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

位运算:

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

3. 判断奇偶

常规操作:

if (n % 2 == 0) {
cout << "Even" << endl;} else {
cout << "Old" << endl;}

位运算:

if ((n & 1) == 0) {
cout << "Even" << endl;} else {
cout << "Old" << endl;}

微信搜索:编程笔记本

微信搜索:编程笔记本
微信搜索:编程笔记本

4. 求平均值

常规操作:

int average(int a, int b){
return (a + b) / 2;}

位运算:

int average(int a, int b){
return (a & b) + ((a ^ b) >> 1);}

5. 计算某数的二进制表示中的 1 的个数

位运算:

int countOne(int num){
int cnt = 0; for (int i = 0; i < 8 * sizeof(num); ++i) {
cnt += num & 1; num >>= 1; } return cnt;}

6. 乘(除)以 2^m

常规操作:

int calculate(int num, int m){
return num * pow(2, m); // return num / pow(2, m);}

位运算:

int calculate(int num, int m){
return num << m; // return num >> m;}

微信搜索:编程笔记本

微信搜索:编程笔记本
微信搜索:编程笔记本

7. 将某数的二进制表示中最右边 1 置零

常规操作:

void setBitZero(int& num){
int mask = 1; for (int i = 0; i < 8 * sizeof(num); ++i) {
if ((num & mask) != 1) {
num ^= mask; break; } }}

位运算:

void setBitZero(int& num){
num = num & (num - 1);}

8. 计算绝对值

常规操作:

int abs(int num){
return num >= 0 ? num : -num;}

位运算:

int abs(int num){
int tmp; tmp = num >> (8 * sizeof(num) - 1); return (num ^ tmp) - tmp; // return (num + tmp) ^ tmp;}

9. 判断某正数是不是 2 的整数次幂

常规操作:

bool isPower2(int num){
int cmp = 1; while (cmp < num) {
cmp *= 2; } return cmp == num;}

位运算:

bool isPower2(int num){
return (num != 0 && (num & (num - 1) == 0));}

微信搜索:编程笔记本

微信搜索:编程笔记本
微信搜索:编程笔记本

10. 找出数据列表中只出现一次的数(其他数都出现了两次)

常规操作:

int showOnece(vector
nums){
int res; map
m; for (auto num : nums) {
++m[num]; } for (auto num : nums) {
if (m[num] == 1) {
res = num; break; } } return res;}

位运算:

int showOnece(vector
nums){
int res = 0; for (auto num : nums) {
res ^= num; } return res;}

11. 小试牛刀:LeetCode_268 缺失数字

题目描述:

给定一个包含 0, 1, 2, ..., nn 个数的序列,找出 0 ... n 中没有出现在序列中的那个数。

示例:

  • 输入: [3, 0, 1]

    输出: 2

  • 输入: [9, 6, 4, 2, 3, 5, 7, 0, 1]

    输出: 8

参考代码:

int missingNumber(vector
& nums) {
int len = nums.size(); int res = len; for (int i = 0; i < len; ++i) {
res ^= i ^ nums[i]; } return res;}

12. 小试牛刀:LeetCode_17.10 主要元素

题目描述:

数组中占比超过一半的元素称之为主要元素。给定一个整数数组,找到它的主要元素。若没有,返回 -1

示例:

  • 输入:[1,2,5,9,5,9,5,5,5]

    输出:5

  • 输入:[3,2]

    输出:-1

参考代码:

int majorityElement(vector
& nums) {
int res= 0; int len = nums.size(); for (int i = 0; i < 8 * sizeof(int); ++i){
int mask = 1 << i; int countOne = 0; for (int j = 0; j < len ; ++j){
if ((nums[j] & mask) != 0) {
++countOne; } } if (countOne > len / 2) {
res ^= mask; } } int countRes = 0; for (int i = 0; i < len ; i++) {
if (nums[i] == res) {
++countRes; } } if (countRes <= len / 2) {
res = -1; } return res;}

微信搜索:编程笔记本

微信搜索:编程笔记本
微信搜索:编程笔记本

转载地址:http://nhkgn.baihongyu.com/

你可能感兴趣的文章
如何友好的处理 WebApi 中抛出的错误
查看>>
因MemoryCache闹了个笑话
查看>>
Dotnet的垃圾回收
查看>>
乘风破浪,.Net Core遇见Dapr,为云原生而生的分布式应用运行时
查看>>
gRPC在C#中的未来属于grpc-dotnet
查看>>
快速排序的性能和名字一样优秀
查看>>
开源推荐:Asp.Net Core入门学习手册!
查看>>
ML.NET 示例:对象检测
查看>>
C#基于yolov3的行人检测
查看>>
ML.NET Cookbook:(16)什么是规范化?为什么我需要关心?
查看>>
WPF 修改(优化)Menu菜单的样式
查看>>
我开发了一款基于web容器的前端项目容器
查看>>
WPF实现环(圆)形菜单
查看>>
WPF 写一个提醒工具软件(完整项目)
查看>>
Windows 11 快速体验:开始菜单居中,全系圆角设计!
查看>>
异步流使用注意事项
查看>>
NET问答: 为什么仅有 getter 的属性,还可以在构造函数中赋值 ?
查看>>
WPF TextBox限制只能输入数字的两种方法
查看>>
【荐】牛逼的WPF动画库:XamlFlair
查看>>
如何绕过 TPM 2.0 安装 Windows 11 操作系统?
查看>>