异或运算的简单应用
问题1:不使用临时变量,实现两个整型变量 x, y 值的交换。
以下为 C++ 实现代码:
1 /************************************************************** 2 author : 林秋伟 3 time : 2013-10-27 4 **************************************************************/ 5 #include <iostream> 6 using namespace std; 7 8 void swap(int &x, int &y){ 9 x^=y; y^=x; x^=y; //使用异或运算交换x与y的值 10 } 11 12 int main(){ 13 int x, y; 14 while(cin>>x>>y){ 15 swap(x, y); 16 cout<<x<<" "<<y<<endl; 17 } 18 return 0; 19 }
问题2:大小为 n=2*k+1 (k≥0) 的整型数组 a, 其中 x 只出现了一次,而其它的数字均出现了两次,要求在 O(n) 时间,O(1) 空间找出 x.
思路:利用 u^0=u, u^v=v^u, u^u=0 的性质可知,a[0]^a[1]^···^a[n-1]=x.
以下是 C++ 实现代码:
1 /************************************************************** 2 author : 林秋伟 3 time : 2013-10-27 4 **************************************************************/ 5 #include <iostream> 6 using namespace std; 7 8 int find(int num[], int n){ 9 int x=0; 10 for(int i=0; i<n; i++) x^=num[i]; 11 return x; 12 } 13 14 int main(){ 15 int n, a[100005]; 16 while(cin>>n){ 17 for(int i=0; i<n; i++) cin>>a[i]; 18 int x=find(a, n); 19 cout<<x<<endl; 20 } 21 return 0; 22 }
问题3:大小为 n=2*k (k≥1) 的整型数组,其中 x, y (x≠y) 只出现了一次,而其它的数字均出现了两次,要求在 O(n) 时间,O(1) 空间找出 x, y.
思路:利用 u^0=u, u^v=v^u, u^u=0 的性质可知,a[0]^a[1]^···^a[n-1]=x^y. 由于 x≠y, 所以 x^y≠0, 即 x^y 的二进制表示中至少有一位为 1, 不妨记该位为 pos, 则可知 x, y 在该位上一个为 0, 一个为 1. 可根据这点将数组分成两组,然后分组进行异或运算,则所得即为 x, y.
以下为 C++ 实现代码:
1 /************************************************************** 2 author : 林秋伟 3 time : 2013-10-27 4 **************************************************************/ 5 #include <iostream> 6 using namespace std; 7 8 int one(int val){ //返回val二进制表示中首个为1的位置 9 int pos=1; 10 while(!(val&1)){ 11 val>>=1; 12 pos++; 13 } 14 return pos; 15 } 16 17 bool judge(int val, int pos){ //判断val二进制表示中第pos位是否为1 18 val>>=(pos-1); 19 return val&1; 20 } 21 22 void find(int num[], int n, int &x, int &y){ 23 int temp=0, i; 24 for(i=0; i<n; i++) temp^=num[i]; 25 int pos=one(temp); 26 x=y=0; 27 for(i=0; i<n; i++){ 28 if(judge(num[i], pos)) x^=num[i]; 29 else y^=num[i]; 30 } 31 } 32 33 int main(){ 34 int n, a[100005], x, y; 35 while(cin>>n){ 36 for(int i=0; i<n; i++) cin>>a[i]; 37 find(a, n, x, y); 38 cout<<x<<" "<<y<<endl; 39 } 40 return 0; 41 }