位运算符
逻辑移位:移位所缺少的数字用“0”来填充
算术移位:移位所缺少的数字用符号位来填充
C语言中,对于常量,如果左移的位数大于了31位,那么结果为0;而对于变量,如果移位的位数 b 大于了该类型的大小 sz ,则先用b对sz取模,即 b = b % sz,然后再进行移位运算
验证:
#include <iostream>
using namespace std;
int main() {
int i=1;
long long j=1;
unsigned k=1;
cout << (1<<35) <<endl;/*常量移位位数超过最大位数为0*/
/*C与java不同,对于非常量,超出都会取模*/
cout << (i<<36) <<endl;/*int型移位超出时进行取模运算,与i<<3结果不相同*/
cout << (i<<3) <<endl;
cout << (j<<65) <<endl;/*long型移位超出时进行取模运算,与j<<6结果不同*/
cout << (j<<6) <<endl;
i = i << 31;
k = k << 31;
cout << (i>>31) <<endl;/*有符号数自然是采用算术运算*/
cout << ((1<<31)>>31) <<endl;/*常量默认按照算术运算*/
cout << k <<" "<<(k>>31)<<endl;/*无符号数采用逻辑运算*/
return 0;
}
应用:
这篇笔记主要是异或^操作的应用
^的作用是:0作^保留,1作^取反。
1、《找出唯一成对的数》
原理:
1、两个相同的数字异或结果为0,0与任何数字异或结果为该数字本身。
2、想要找到重复的那个数,则需要消除其他的数。
3、已知数组内所有的数字中只有两个数字重复,其他数字全部在1~N之间,即数组由1~N中每个数+1~N中任意一个数字组成。那么用1~N个数字与数组中的元素全部异或,每对不重复数字异或结果为0,重复数字由于共有三个,所以这个异或最终的结果就是那个重复数字。
/*找到重复的那个数*/
#include <iostream>
#include <stdlib.h>
using namespace std;
#define MAX 100000
int arr[MAX];
int main() {
int N=10;/*N+1表示数据总个数,与视频中的意思不一样*/
//cin >> N;
int i;
for(i=0; i<N; i++){
arr[i] = i+1;
}
arr[N] = (rand() % N)+ 1;/*从1~N中随机产生一个数*/
//arr[N] = 8;/*从1~N中随机产生一个数*/
int x1 = 0;
for(i=1; i<=N; i++){
x1 = (x1^i);
}
for(i=0; i<=N; i++){
x1 = (x1^arr[i]);
cout << arr[i] << " ";
}
cout << endl;
cout << x1 <<endl;
return 0;
}
注意这种方法的应用有局限性,只能在知道其他单个的数据具体是什么的时候才能使用。
如果不知道其他数据到底是怎样的,那么只能借助辅助空间来解决。
2、《找出落单的那个数》
这个题比上一道要简单的多,就不详细写了,核心代码如下:
x1 = 0;
for(i=0; i<=N; i++){//N表示数据总个数
x1 = (x1^arr[i]);
cout << arr[i] << " ";
}