黑马程序员技术交流社区

标题: 请问下这段代码怎么完成的数据置换 [打印本页]

作者: HM马强    时间: 2013-9-22 16:56
标题: 请问下这段代码怎么完成的数据置换
本帖最后由 HM马强 于 2013-10-5 15:44 编辑

求解,
int a = 3;
int b = 5;
a = b + ( b = a )  - b ;
话说这是我从百度上看到的一段代码,一句就可以完成数据置换,谁能帮我说说是怎样完成的么?{:soso_e134:}

作者: 黑色海    时间: 2013-9-22 17:30
看不懂,等高手来解释
作者: yxz    时间: 2013-9-22 17:31
本帖最后由 yxz 于 2013-9-22 17:33 编辑

说实话,这道题的刁钻程度称得上面试级的了。
我刚才自己写了点代码才算搞明白了。
int a=5;
System.out.print(a+(a=1));
这样结果是6
int a=5;
System.out.print((a=1)+a);
这样结果是2
这说明解释器加载顺序是从左到右的。
再看LZ的问题。
b + ( b = a )  - b
括号最先被执行,前面一个b是被加载之前b的原始值,后面一个b最后加载,是括号里赋值运算之后的值
也就是换句话说。
a = b + ( b = a )  - b ;
这个东西可以拆解为
a = 6 + (6 = 3) - 3;
结果就是b=3,a=6。
为了证明我之前的逻辑,我用Python跑了一下,不通过,然后用C语言跑了一下,结果错误。
说明通用性不是很强。
作者: HM马强    时间: 2013-9-22 17:33
yxz 发表于 2013-9-22 17:31
说实话,这道题的刁钻程度称得上面试级的了。
我刚才自己写了点代码才算搞明白了。
int a=5;

那也就是说只有在java中是这样,别的语言中就不可以了啊?

作者: yxz    时间: 2013-9-22 17:45
JavaScript也可以,不过好像视频里提到过一种更好的按位算法也可以一步到位,我找找看
作者: 王清华0    时间: 2013-9-22 17:48
两个要素:
第一,b=a这个赋值表达式是有值的,值等于a。
  1.         public static void main(String[] args)
  2.         {
  3.                 int a=3;
  4.                 int b=5;
  5.                 System.out.println(b=a);
  6.         }
复制代码
控制台输出:3
第二,java表达式右侧执行顺序是自左至右。
  1.         public static void main(String[] args)
  2.         {
  3.                 int a=3;
  4.                 int b=5;
  5.                 System.out.println(b+(b=a));
  6.         }
复制代码
控制台输出:8
也就是说,自左至右,开始执行的时候,第一个b的值为5;
执行到+(b=a)时,将a的值赋予b,并且将这个赋值表达式的值3(就是a的值)与5相加,此时表达式的值等于8了;
执行到-b的时候,b的值此时已经被赋值为3,因此表达式的值为8-3=5,从而将5赋予=左端的a。
这样在 一步之内完成数据置换。

作者: yxz    时间: 2013-9-22 17:58
本帖最后由 yxz 于 2013-9-22 17:59 编辑
  1. int a = 6, b = 5;

  2. a = a ^ b;
  3. b = b ^ a;
  4. a = b ^ a;
  5. System.out.println("a=" + a + "b=" + b);

  6. //简写
  7. a = ((b = b ^ (a = a ^ b)) ^ a);
  8. System.out.print("a=" + a + "b=" + b);
复制代码
这样写也可以一步到位,目测在其他语言里可以通用。
作者: nineteen73    时间: 2013-9-22 20:45
  1.         int a = 3;
  2.                 int b = 5;
  3.                 a = b + ( b = a )-b ;
  4.                 System.out.println(a);
  5.                 System.out.println(b);
  6.                 System.out.println("=======================");
  7.                 b=a+(a=b)-a;
  8.                 System.out.println(a);
  9.                 System.out.println(b);
复制代码
我把代码有往下扩展了下,结果是:
5   3
3   5
对于a = b + ( b = a )-b ;括号里b=a,是把a赋给b,b变成了3,括号后的b也变成了3,但是括号前的b还是5,
不受影响,所以a=5+(3)-3,a就等于5了,下边的b=a+(a=b)-a也是一样的,有变了回来,你可以debug下试试
作者: 黄文伯    时间: 2013-9-22 21:09
亲,如问题已解决请将分类的“未解决”改为“已解决”。
以后的问题贴也要及时更改分类哦~
作者: HM马强    时间: 2013-9-23 12:53
黄文伯 发表于 2013-9-22 21:09
亲,如问题已解决请将分类的“未解决”改为“已解决”。
以后的问题贴也要及时更改分类哦~ ...

版主大哥,怎么改啊...我不知道啊...

作者: Leo_yeung    时间: 2013-10-4 22:40
这个是利用两个数的和值,不通过第三方变量来实现连个变量的置换的;
表达式a = b + ( b = a )  - b ;中,在赋值号的右边,b是原来的值,然后(b=a)将a的值赋给b,最后一个b的值也已经是a赋给它的值,所以赋值号右边就等同于b+a-a,所以在这样实现了两个变量值的置换。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2