博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
异或运算 ^ 变量交换及找出现一次的数
阅读量:4141 次
发布时间:2019-05-25

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

一、交换2个变量

如果想要交换2个变量,一般的做法是引入第三个变量,

例如,

[cpp] 
  1. temp = a;  
  2. a = b;  
  3. b= temp;  

这样2个变量中的值就实现了交换。那能不能不引入其他变量就可以实现变量值的交换呢?答案是肯定的。

用异或操作可以实现,有2种实现方法,本质上是一样的。

法1:

[cpp] 
  1. #include <stdio.h>  
  2. int main()  
  3. {  
  4.     int a,b;  
  5.     while(1)  
  6.     {  
  7.         scanf("%d %d",&a,&b);  
  8.         a = a^b;          //(1)  
  9.         b = a^b;          //(2)  
  10.         a = a^b;          //(3)  
  11.         printf("%d %d\n",a,b);  
  12.     }  
  13.     return 0;  
  14. }  

法2:

[cpp] 
  1. #include <stdio.h>  
  2. int main()  
  3. {  
  4.     int a,b;  
  5.     while(1)  
  6.     {  
  7.         scanf("%d %d",&a,&b);  
  8.         b = a^b;        //(1)  
  9.         a = a^b;        //(2)  
  10.         b = a^b;        //(3)  
  11.         printf("%d %d\n",a,b);  
  12.     }  
  13.     return 0;  
  14. }  

因为2种方法本质一样,就方法一进行一下证明。

异或操作满足结合律和交换律,且由异或操作的性质知道,对于任意一个整数a^a=0;

证:(第(2)步中的a) a = a^b = (将第(1)步中的b代入b) a^(a^b) = b;

(第(3)步中的b)b = a^b = (将第(1)步中的b代入b,将第(2)步中的a代入a) a^b^a^a^b = a^a^a^b^b = a;

证毕

http://blog.csdn.net/love_cppandc/article/details/7023238

二、求出现一次的数

题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字

这道题利用异或的几个性质:任何数与其本身异或值都为0,异或运算满足交换律。因此将一组数依次异或,若里面只有一个只出现一次的数,其他的数都出现两次,则最后的结果必然是那个只出现一次的数。要找到两个数字就可以先通过异或整个数组,将得到的结果分组。然后依次安组异或就可以得到所求的值~

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include<iostream>
using 
namespace 
std;
int 
findFirstOne(
int 
value);
bool 
testBit(
int 
value,
int 
pos);
int 
findNums(
int 
date[],
int 
length,
int 
&num1,
int 
&num2){
    
if
(length<2){
return 
-1;}
    
int 
ansXor=0;
    
for
(
int 
i=0;i<length;i++){
        
ansXor^=date[i];              
//异或
    
}
    
int 
pos=findFirstOne(ansXor);
    
num1=num2=0;
    
for
(
int 
i=0;i<length;i++){
        
if
(testBit(date[i],pos))
            
num1^=date[i];
        
else
            
num2^=date[i];
    
}
    
return 
0;
}
int 
findFirstOne(
int 
value){    
//取二进制中首个为1的位置
    
int 
pos=1;
    
while
((value&1)!=1){
        
value=value>>1;
        
pos++;
    
}
    
return 
pos;
}
bool 
testBit(
int 
value,
int 
pos){ 
//测试某位置是否为1
    
return 
((value>>pos)&1);
}
int 
main(
void
){
    
int 
date[10]={1,2,3,4,5,6,4,3,2,1};
    
int 
ans1,ans2;
    
if
(findNums(date,10,ans1,ans2)==0)
        
cout<<ans1<<
" "
<<ans2<<endl;
    
else
        
cout<<
"error"
<<endl;
    
return 
0;
}
你可能感兴趣的文章
在osg场景中使用GLSL语言——一个例子
查看>>
laravel 修改api返回默认的异常处理
查看>>
laravel事务
查看>>
【JavaScript 教程】浏览器—History 对象
查看>>
这才是学习Vite2的正确姿势!
查看>>
7 个适用于所有前端开发人员的很棒API,你需要了解一下
查看>>
25个构建Web项目的HTML建议,你需要了解一下!
查看>>
【web素材】02-10款大气的购物商城网站模板
查看>>
6种方式实现JavaScript数组扁平化(flat)方法的总结
查看>>
49个在工作中常用且容易遗忘的CSS样式清单整理
查看>>
20种在学习编程的同时也可以在线赚钱的方法
查看>>
隐藏搜索框:CSS 动画正反向序列
查看>>
127个超级实用的JavaScript 代码片段,你千万要收藏好(上)
查看>>
【视频教程】Javascript ES6 教程27—ES6 构建一个Promise
查看>>
【5分钟代码练习】01—导航栏鼠标悬停效果的实现
查看>>
127个超级实用的JavaScript 代码片段,你千万要收藏好(中)
查看>>
127个超级实用的JavaScript 代码片段,你千万要收藏好(下)
查看>>
【web素材】03-24款后台管理系统网站模板
查看>>
Flex 布局教程:语法篇
查看>>
年薪50万+的90后程序员都经历了什么?
查看>>