A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© cro 初级黑马   /  2012-6-8 11:58  /  2534 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

哪位能解释一下下面a与b是怎么实现位置交换的,求详细过程,我看了半天也没弄懂!多谢了!!

public class TestTalk {

public static void swapAb(int a, int b) {
  //以下位置交换算法怎么理解
   a = a ^ b;
   b = a ^ b;
   a = a ^ b;
}

public static void main(String[] args) {
  int i = 10, j = 5;
  TestTalk.swapAb(i, j);
  
  System.out.println(i); //测试时,i和j的输出值并没有看到交换位置!这是为什么!
  System.out.println(j);
}
}

7 个回复

倒序浏览
本帖最后由 田建 于 2012-6-8 12:25 编辑

首先你要知道,一个数异或同一个数两次还是这个数,第一步:a=a^b;(把a异或b的值赋给了a);第二步:b=a^b;(此时的a已经是a^b的值,再异或b即等于了a,达到了把a赋给b的目的);第三步:a=a^b;(此时的a等于a^b,而b等于a,因而此时的a^b=a^b^a=b,从而达到了把b赋给a的目的)!经过以上三步a和b的值就交换了,值进行交换的方式总共有3种,这只是一种技巧性方式,真正开发过程中记住第三方变量的方法才是最实用的!
而你下面的打印之所以没有交换,是因为,你打印的还是主函数中的i和j,你需要把两条打印语句放到swapAb( )里面去!

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

回复 使用道具 举报
本帖最后由 曹昌 于 2012-6-8 12:37 编辑

我们先来回顾一下异或  

^ 异或 特点:同为假,异为真 规律:一个数同时异或这个数两次结果还是这个数。用于加密

所以这个就很好理解了哦

public class TestTalk {
public static void swapAb(int a, int b) {
  //以下位置交换算法怎么理解    //解答:^ 异或 特点:同为假,异为真 规律:一个数同时异或这个数两次结果还是这个数。用于加密


   a = a ^ b;
   b = a ^ b;
   a = a ^ b;
}

public static void main(String[] args) {
  int i = 10, j = 5;
  
   
   int a = a ^ b;
   b = a ^ b;
   a = a ^ b;
  System.out.println(i); //测试时,i和j的输出值并没有看到交换位置!这是为什么!   解答:因为swapAb方法返回值,或者直接把主函数的输出语句直接放swap()方法里面,这是两个原因 两个解决办法
  System.out.println(j);
}



补充:异或的用法

相同输出0,不同输出1,例如:
System.out.println(1^1); 输出0
System.out.println(1^2);输出3,因为最后2个低位都不一样,所有输出3

    异域的概念是相同为0不同为1.如果两个数值异或后的值相同,异或前可能不同。
比如二进制:0010^0001=0011 而0000^0011=0011。 异或要慎用。


回复 使用道具 举报
public class TestTalk {
public static void swapAb(int a, int b) {
  //以下位置交换算法怎么理解
   a = a ^ b;                  
   b = a ^ b;              
   a = a ^ b;
}
public static void main(String[] args) {
  int i = 10, j = 5;  
  TestTalk.swapAb(i, j);  //这里有问题哦  传递的是副本哦 这里的i 和j没有改变
  
  System.out.println(i); //测试时,i和j的输出值并没有看到交换位置!这是为什么!
  System.out.println(j);
}
}

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

回复 使用道具 举报
用异或注意下自己跟自己交换变量的值为0  
回复 使用道具 举报
package temp;
public class TestTalk {
public static void swapAb(int a, int b) {
  //以下位置交换算法怎么理解
   a = a ^ b;
   /*
     0000 1010
     0000 0101
     ----------
     0000 1111*/

   b = a ^ b;
/*   0000 1111
     0000 0101
     -------------
     0000 1010

*/ a = a ^ b;
/*   0000 1111
     0000 1010
    ---------------
     0000 0101
     */

}
public static void main(String[] args) {
  int i = 10, j = 5;
  // 10 (0000 1010) 5(0000 0101) 二进制
  TestTalk.swapAb(i, j);
  
  System.out.println(i); //测试时,i和j的输出值并没有看到交换位置!这是为什么!
  System.out.println(j); //因为只是进行了值传递;并没有返回修改后值的引用;
  
}
}
//就是使用异或进行位操作; 上面 注释只写了2个字节;int型是 4个字节的 ,省略没有 写出来

评分

参与人数 2技术分 +1 黑马币 +4 收起 理由
cro + 4 很给力!
黄奕豪 + 1 赞一个!

查看全部评分

回复 使用道具 举报
你输出语句放错位置了,你要知道赋值语句的存储方式。
  1. package pack;

  2. public class TestTalk {
  3. public static void swapAb(int a, int b) {
  4.   //以下位置交换算法怎么理解
  5.    a = a ^ b;
  6.    b = a ^ b;
  7.    a = a ^ b;
  8.    System.out.println(a); //测试时,i和j的输出值并没有看到交换位置!这是为什么!
  9.    System.out.println(b);
  10. }
  11. public static void main(String[] args) {
  12.   int i = 10, j = 5;
  13.   TestTalk.swapAb(i, j);
  14.   
  15.   
  16. }
  17. }
复制代码
回复 使用道具 举报

你记着一句:一个数同时异或另一个数两次,那么结果还是这个数
a = a ^ b;                  
b = a ^ b;  //到这里时,a已经被赋值是(a^b)  那么这个表达式的完整写法就是  b = a^b^b   结果b = a              
a = a ^ b; // 同上,这个完整的写法就是  a = a^a^b   那么结果就是a = b;   
这样就形成互换了.
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马