楼主: yujianta14
702 0

大数据Java-交换变量的 3 种方式 [推广有奖]

  • 0关注
  • 0粉丝

本科生

36%

还不是VIP/贵宾

-

威望
0
论坛币
130 个
通用积分
0
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
1703 点
帖子
45
精华
0
在线时间
10 小时
注册时间
2016-4-18
最后登录
2016-6-27

楼主
yujianta14 发表于 2016-4-18 16:05:17 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
本话题要讨论的是一道面试题目:交换两个变量的值。两个变量而已,看似再简单不过了,不过一道简单的题目可以使用多种方式来完成, 其中有比较普通的实现, 也有相对高明的实现,虽然是一道简单的题目,但是通过面试者对该题目的认知能力,就可以看出面试者的水平。
重点摘要:
1 通过中间变量交换。
2 通过求和与求差交换。
3 通过异或交换。
通过第 3 个变量
首先,我们给出最简单的方式。
【例】 交换两个变量的值。
  1. 1.package chapter2;
  2. 2.
  3. 3. public class Swap {
  4. 4. public static void main(String[] args) {
  5. 5. int x = 5;
  6. 6. int y = 10;
  7. 7. swap(x, y);
  8. 8. System.out.println(x);
  9. 9. System.out.println(y);
  10. 10. Value v = new Value(5, 10);
  11. 11. swap(v);
  12. 12. System.out.println(v.x);
  13. 13. System.out.println(v.y);
  14. 14. }
  15. 15. //无效的交换
  16. 16. public static void swap(int x, int y) {
  17. 17. int temp = x;
  18. 18. x = y;
  19. 19. y = temp;
  20. 20. }
  21. 21. //有效的交换
  22. 22. public static void swap(Value value) {
  23. 23. int temp = value.x;
  24. 24. value.x = value.y;
  25. 25. value.y = temp;
  26. 26. }
  27. 27.}
  28. 28.
  29. 29.class Value {
  30. 30. int x;
  31. 31. int y;
  32. 32.
  33. 33. public Value(int x, int y) {
  34. 34. this.x = x;
  35. 35. this.y = y;
  36. 36. }
  37. 37.}
复制代码

程序运行结果如下:
  1. 5
  2. 10
  3. 10
  4. 5
复制代码

这个程序同时给出了有效的交换(第 22~26 行)与无效的交换(第 16~20 行)。因为形参的改变是无法反作用于实参的,所以不能使用变量交换的方式,而是要使用通过引用来修改其成员变量的方式。这就类似与 C / C++的语言中的指针效果。
通过相加的方式

通过第 3个临时变量,可以成功交换两个变量的值,不过,有时,面试题目的要求会比较苛刻,就是不允许借助于临时变量。这样,就有些复杂了。
【例】 交换两个变量的值2。

  1. 1.package chapter2;
  2. 2.
  3. 3. public class Swap2 {
  4. 4. public static void main(String[] args) {
  5. 5. Value v1 = new Value(5, 10);
  6. 6. swap(v1);
  7. 7. System.out.println("v1的交换结果: ");
  8. 8. System.out.println(v1.x);
  9. 9. System.out.println(v1.y);
  10. 10. Value v2 = new Value(1200000000, 1500000000);
  11. 11. swap(v2);
  12. 12. System.out.println("v2的交换结果: ");
  13. 13. System.out.println(v2.x);
  14. 14. System.out.println(v2.y);
  15. 15. Value v3 = new Value(-1200000000, -1500000000);
  16. 16. swap(v3);
  17. 17. System.out.println("v3的交换结果: ");
  18. 18. System.out.println(v3.x);
  19. 19. System.out.println(v3.y);
  20. 20. }
  21. 21.
  22. 22. public static void swap(Value v) {
  23. 23. v.x = v.x + v.y;
  24. 24. v.y = v.x - v.y;
  25. 25. v.x = v.x -v.y;
  26. 26. }
  27. 27.}
复制代码

程序运行结果如下:
v1的交换结果:
  1. 10
  2. 5
复制代码

v2的交换结果:
  1. 1500000000
  2. 1200000000
复制代码

v3的交换结果:
  1. -1500000000
  2. -1200000000
复制代码

核心部分就是 swap 方法(第 22~26 行),该方法的 3 条语句解释为:
  1. v.x = v.x + v.y; //将v.x与v.y的和存储在v.x中
  2. v.y = v.x - v.y; //v.x – v.y的值就是以前v.x的值,赋值给v.y
  3. v.x = v.x -v.y; //v.x – v.y的值就是以前v.y的值,赋值给v.x
复制代码

这样,没有通过临时变量,也同样交换了两个变量的值。也许上面的方法一时不太容易理解,那么可以这样考虑:
  1. int z = v.x + v.y;
  2. v.y = z – v.y;
  3. v.x = z - v.y;
复制代码


只不过这里使用另外一个变量 z,而上面使用 v.x 来存储 v.x 与 v.y 的和,但是交换的效果是相同的。
注意程序的第 10 行与第 15 行, v.x 与 v.y 的初始值非常大(小),这样一来,当执行swap方法时(以第 10 行为例):
  1. v.x = v.x + v.y;
复制代码


十六进制求和如下所示:
47868c00( v.x)
+ 59682f00( v.y)
结果: a0eebb00( v.x + v.y)
注意这个结果的最高位为 1,结果为负数(十进制值为−1594967296,也就是 v.x 与 v.y 的和已经超过了 int 类型的最大(小)值,发生溢出。
执行接下来的语句:
  1. v.y = v.x - v.y;
复制代码

这个计算就是使用溢出后的值−1594967296 减去 v.y( 1500000000),从 int 类型的求差角度来说,结果再一次溢出了,十六进制求差如下所示:
a0eebb00( v.x + v.y)
− 59682f00( v.y)
结果: 47868c00(结果 v.y)
经过两次溢出以后,又再次得出了我们期望的值。同样, swap 方法的第 3 条语句:
  1. v.x = v.x -v.y;
复制代码

a0eebb00( v.x + v.y)
− 47868c00( v.y)
结果: 59682f00(结果 v.x)
也是发生了溢出,不过最后的差值也得出了期望的结果。可以看出,当两个数之和很大(小)时,虽然发生了溢出,不过最后还是阴差阳错地得到了正确的结果。尽管结果正确,这种相加的方式还不算十分可取。

通过异或的方式
位异或运算符( ^)有这样一个性质,就是两个整型数据 x 与 y,有:
  1. (x ^ y ^ y) == x
复制代码


这说明,如果一个变量 x 异或另外一个变量 y 两次,结果为 x。通过这一点,可以实现交换变量的值。
【例】 交换两个变量的值 3。

  1. 1.package chapter2;
  2. 2.
  3. 3. public class Swap3 {
  4. 4. public static void main(String[] args) {
  5. 5. Value v = new Value(5, 10);
  6. 6. swap(v);
  7. 7. System.out.println(v.x);
  8. 8. System.out.println(v.y);
  9. 9. }
  10. 10.
  11. 11. public static void swap(Value v) {
  12. 12. v.x = v.x ^ v.y;
  13. 13. v.y = v.x ^ v.y;
  14. 14. v.x = v.x ^ v.y;
  15. 15. }
  16. 16.}
复制代码

程序运行结果如下:
  1. 10
  2. 5
复制代码

swap 方法(第 11~15 行)并不复杂,只有 3 条语句:
  1. v.x = v.x ^ v.y; (1)
  2. v.y = v.x ^ v.y; (2)
  3. v.x = v.x ^ v.y; (3)
复制代码


可以这样看:执行( 1)后, v.x 的值就是 v.x(异或运算之前的值)与 v.y 异或后的结果。类似数学上的代入法,将 v.x(值为 v.x ^ v.y)代入( 2)中,于是( 2)赋值运算符( =右侧的表达式相当于:

  1. v.x ^ v.y ^ v.y //v.x与v.y都是运算之前的值
复制代码


这个值就是 v.x(异或运算之前的值)、然后赋值给左侧的 v.y。此时, v.y 的值就是异或运算之前 v.x 的值。然后将 v.x(值为 v.x ^ v.y)、 v.y(值为异或运算之前 v.x 的值)代入(3)中赋值运算符右侧,代入后表达式相当于:

  1. v.x ^ v.y ^ v.x //v.x与v.y都是运算之前的值
复制代码


这个值就是 v.y,然后赋值给 v.x,至此,完成两个变量的交换。异或方式要比相加方式更加可取,因为异或运算不涉及溢出。综合这 3 种方式而言,第 1 种方式最容易理解,第 3 种方式相对成熟老练,如果是个人编写程序,建议还是使用最简单的方式,这样不容易出错,而且代码具有可读性,便于后期的维护,如果是在面试过程中,那就可以选择第 3 种方式来证明下自己的能力。
总结:
1.        一个变量 x 异或另一个变量 y 两次,结果的值为 x。
2. 异或运算可以交换两个变量的值,并且这种方式比相加交换的方式更可取些。

举一反三
既然相加(第 2 种方式)能够实现交换两个变量的值,那么相减肯定也能实现。编写一个程序,不要借助第 3 个临时变量,实现相减操作交换两个变量的值。

本文出自柠檬派http://www.lemonpai.com   请务必保留此出处 ,否则将追究法律责任!

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:Java 大数据 jav Chapter package public Java 能力 大数据

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
jg-xs1
拉您进交流群
GMT+8, 2026-1-11 12:38