位运算算法篇:异或运算
创作时间:
作者:
@小白创作中心
位运算算法篇:异或运算
引用
CSDN
1.
https://m.blog.csdn.net/2301_80260194/article/details/145532893
位运算中的异或运算是一种非常有趣且实用的运算方式。它不仅在算法设计中有着广泛的应用,而且其独特的性质和规则也使得它成为计算机科学领域的一个重要知识点。本文将从异或运算的基本原理出发,深入探讨其在实际编程中的多种应用场景,帮助读者全面理解并掌握这一运算方式。
1. 原理
(1). 无进位相加
异或运算的规则是"相同为0,相异为1"。为了更好地理解这个规则,我们可以将其理解为"无进位相加"。在二进制加法中,逢二进一的原则会导致两个1相加时产生进位,而异或运算则不会产生这样的进位。例如:
10011001 ^ 11110101
10011001
+11110101
——————
01101100
(2). 异或运算的性质
异或运算满足交换律和结合律。对于任意四个数a、b、c、d,它们的异或运算结果与运算顺序无关:
a ^ b ^ c ^ d = a ^ c ^ b ^ d = (a ^ c) ^ d ^ b = (a ^ (c ^ b) ^ d)
异或运算的另一个重要性质是:任何数与0异或等于其本身,任何数与自身异或等于0。这个性质可以推广到多个相同数的异或运算中:
- 偶数个相同数异或的结果为0
- 奇数个相同数异或的结果为该数本身
这个性质在解决某些特定问题时非常有用。例如,已知一个序列的整体异或和c,以及该序列一部分的异或和b,要找到另一部分的异或和a,可以通过以下方式计算:
c = a ^ b
a = c ^ b ^ b = a ^ (b ^ b) = a ^ 0 = a
2. 应用
(1). 交换两个数
要交换两个数a和b的值,可以使用异或运算:
#include<iostream>
using namespace std;
int main()
{
int a=10,b=20;
cout<<"before: "<<a<<" "<<b<<endl;
a=a^b;
b=a^b;
a=a^b;
cout<<"After: "<<a<<" "<<b<<endl;
return 0;
}
(2). 找到缺失的数
在一个连续区间中找到缺失的数,可以使用异或运算:
#include<iostream>
using namespace std;
int main()
{
int arr[]={1,2,3,4,5,6,7,8,10};
int ret=0;
for(int i=1;i<=10;i++)
{
ret^=i;
}
int ret2=0;
for(int i=0;i<sizeof(arr)/sizeof(int);i++)
{
ret2^=arr[i];
}
ret=ret^ret2;
cout<<ret<<endl;
return 0;
}
(3). 比较两个数的大小
使用位运算比较两个数的大小,不使用条件判断语句:
#include<iostream>
using namespace std;
void getmax(int a,int b)
{
int c=a-b;
int returnB=(c>>31)&1;
int returnA=1-returnB;
int res=a*returnA+b*returnB;
cout<<"the max is:"<<res<<endl;
return;
}
int main()
{
int a=20,b=10;
getmax(a,b);
a=10,b=30;
getmax(a,b);
return 0;
}
(4). 找到出现为奇数次的数
在一个序列中找到出现奇数次的数:
#include<iostream>
using namespace std;
int main()
{
int arr[]={1,1,1,2,2,3,3,4,4,5,5};
int ret=0;
for(int i=0;i<sizeof(arr)/sizeof(int);i++)
{
ret^=arr[i];
}
cout<<ret<<endl;
return 0;
}
(5). 找到两个不同出现奇数次的数
在一个序列中找到两个出现奇数次的数:
#include<iostream>
using namespace std;
int main()
{
int arr[]={1,1,1,2,2,3,3,4,4,5,5,7,7,7};
int ret=0;
for(int i=0;i<sizeof(arr)/sizeof(int);i++)
{
ret^=arr[i];
}
int check=ret&(-ret);
int ret2=0;
for(int i=0;i<sizeof(arr)/sizeof(int);i++)
{
if((check&arr[i])!=0)
{
ret2^=arr[i];
}
}
ret=ret^ret2;
cout<<ret<<" "<<ret2<<endl;
return 0;
}
(6). 找到出现次数小于m次的数
在一个序列中找到出现次数小于m次的数:
#include <iostream>
#include <vector>
using namespace std;
int findNumberAppearingLessThanMTimes(const vector<int>& nums, int m) {
int result = 0;
int bitCount[32] = {0}; // 用于统计每一位上1的个数
// 遍历每一位
for (int i = 0; i < 32; ++i) {
for (int num : nums) {
// 检查num的第i位是否为1
if (num & (1 << i)) {
bitCount[i]++;
}
}
// 如果第i位上1的个数不是m的倍数,则结果的第i位为1
if (bitCount[i] % m != 0) {
result |= (1 << i);
}
}
return result;
}
int main() {
vector<int> nums = {2, 2, 3, 3, 3, 4, 4, 4, 4}; // 示例序列
int m = 3; // 其他数出现的次数
int result = findNumberAppearingLessThanMTimes(nums, m);
cout << "The number appearing less than " << m << " times is: " << result << endl;
return 0;
}
3. 结语
异或运算在计算机科学中有着广泛的应用,从基础的位操作到复杂的算法设计,都能看到它的身影。通过本文的介绍,相信读者对异或运算有了更深入的理解。希望这些知识能为你的编程之路提供帮助。
热门推荐
新房装修,卧室这样装多出一个梳妆台,好看又好用
微信群聊管理与沟通技巧:提升交流效率与氛围的实用指南
《功夫熊猫4》衍生动漫推荐:从大银幕到小屏幕的精彩延续
离职前的心理准备,你真的了解吗?
糖尿病患者能安心吃代糖吗?ADA专家分享颠覆认知
耳鸣患者的护耳秘籍:从日常护理到专业治疗
日本教科书淡化南京大屠杀:历史教育的缺失与反思
南京大屠杀纪念馆:夏淑琴的坚韧与正义
阳江沙扒湾:中国的马尔代夫,绝美自然景观等你探索
阳江沙扒湾:阳光海浴、海鲜美食与海岛探险的完美融合
二十句优雅催账,教你追债不伤感情
催收班里的心理战术:企业老板如何讨回"消失"的欠款?
法律途径追债全攻略:从立案到执行
法院教你合法追债,再也不怕赖账鬼
@持卡人,你开通账户变动短信通知了没?江苏省消保委调查18家银行出了报告
自驾游北京,进京通行证怎么搞?
双旦假期,沪京高铁VS飞机谁更快?
G28次列车:沪京最快高铁揭秘
通海秀山公园:云南四大名山之一,融历史文化与自然景观于一体
阳泉:萝卜快跑如何成为地方经济新引擎
诸葛亮最强秒人出装打野攻略:让你成为无敌战神
诸葛亮打野出装和玩法攻略(解析诸葛亮打野的优势和策略,带你领略非凡视野)
诸葛亮出装六神装 最强打野,国服第一诸葛亮最强出装铭文
《熊出没》:让孩子在欢笑中养成好习惯
《熊出没·有爱就不怕》:用动画传递爱与勇气
编程判断奇数偶数什么结构
南京大屠杀认知差异再掀波澜,中日关系受考验
五一档票房大战:《九龙城寨之围城》与《哥斯拉大战金刚2》的对决
横纹困扰?教你如何解决电视机横纹问题
阳明山国家公园:台北的自然瑰宝,四季皆宜的旅游胜地