基本的位操作:
| --->或操作
&--->与操作
^---->异或操作
~--->取反
<<-->左移
>>-->右移
题1:在一个序列中,只有一个数出现奇数次,请你找出这个数。
解:arr[5]={1,1,2,2,3}
1^1=0 2^2=0
所以:1^1^2^2^3=3 ok,搞定
//1.在arr中,只有一种数,出现奇数次,找出这个数
void printOddTimesNum(int arr[],int len){
int eor = 0;
for(int i=0;i<len;i++){
eor = eor^arr[i];
}
printf("唯一的那个奇数为:%d\n",eor);
}
题2:在一个需要序列中,有两种数出现奇数次,求出这两个数。
解:arr[6]={1,1,2,2,3,4}
eor = 1^1^2^2^3^4=3^4
然后将eor的二进制中的最右边的为1的取出来。
eor & (~eor+1)
为什么这样做呢?因为我们知道异或操作是,不同为1,则说明在这一位二进制数的状况,这两个奇数是不同的。eor=3^4=0011^0100=0111
0111-->1000-->1001-->1001&0111=0001
如此以来,我们就可以将这个序列中的数分为两堆,一堆是这个位上是1的,一堆是这个位上不是1
那么,3和4肯定是在不同的堆中的。
1、1、3和2、2、4-->我们就可以求出这两个数了,跟只有一个数出现奇数次的情况一样
//arr中,有两种数,出现的奇数次,找出这两个数
void printOddTimesNum2(int arr[],int len){
int eor = 0;
//找到那两个出现奇数次异或的结果
for(int i=0;i<len;i++){
eor = eor^arr[i];
}
//取出eor中的二进制的最右边的1-->这样我们可以把数组分为第i位上是1的和第i位上不是1的
int tmp = eor & (~eor+1);
int numOne = 0;
for(int i=0;i<len;i++){
if((tmp & arr[i]) == 1){
numOne = numOne^arr[i];
}
}
printf("%d,%d\n",numOne,eor^numOne);
}
题3:求出整数num的二进制上为1的个数
解:不断地取出num的最右边的1
//取出一个整数的二进制为1的个数
void bitcounts(int num){
int count = 0;
while (num != 0)
{
int rightOne = num & (~num + 1); //取出最右边的1
count++;
num = num ^ rightOne; //将最右边的1变成0
}
printf("这个整数的二进制为1的个数为:%d\n",count);
}
测试代码附上:
#include <iostream>
#include <cstdlib>
using namespace std;
#define MAX_SIZE 100
//1.在arr中,只有一种数,出现奇数次,找出这个数
void printOddTimesNum(int arr[],int len){
int eor = 0;
for(int i=0;i<len;i++){
eor = eor^arr[i];
}
printf("唯一的那个奇数为:%d\n",eor);
}
//arr中,有两种数,出现的奇数次,找出这两个数
void printOddTimesNum2(int arr[],int len){
int eor = 0;
//找到那两个出现奇数次异或的结果
for(int i=0;i<len;i++){
eor = eor^arr[i];
}
//取出eor中的二进制的最右边的1-->这样我们可以把数组分为第i位上是1的和第i位上不是1的
int tmp = eor & (~eor+1);
int numOne = 0;
for(int i=0;i<len;i++){
if((tmp & arr[i]) == 1){
numOne = numOne^arr[i];
}
}
printf("%d,%d\n",numOne,eor^numOne);
}
//取出一个整数的二进制为1的个数
void bitcounts(int num){
int count = 0;
while (num != 0)
{
int rightOne = num & (~num + 1); //取出最右边的1
count++;
num = num ^ rightOne; //将最右边的1变成0
}
printf("这个整数的二进制为1的个数为:%d\n",count);
}
int main(){
int len=0;
int arr[MAX_SIZE];
printf("长度:");
scanf("%d",&len);
printf("序列:");
for(int i=0;i<len;i++){
scanf("%d",&arr[i]);
}
//测试1
printOddTimesNum(arr,len);
//测试2
printOddTimesNum2(arr,len);
//测试3 5-->00000101
bitcounts(5);
system("pause");
return 0;
}