黑马程序员技术交流社区

标题: 关于位运算的一个小问题 [打印本页]

作者: 王莹    时间: 2012-6-15 20:43
标题: 关于位运算的一个小问题
本帖最后由 王莹 于 2012-6-17 08:20 编辑

在第02天—15-位运算符(练习)这个视频中,做了一个关于调换两个变量位置的练习题,其中,用的是位运算这个方法的程序,我觉得有点想不通,请教一下各位。

第7句:m=n^m;
此句中,n已经变化,可以等价于(n^m)^m,是对的

第8句: n=n^m;
但这句中,n和m均变化了,可以等价为(n^m)^(n^m^m),其中(n^m^m)等价为n,也就是整体变为了(n^m)^n,这样并不是连续异或同一个数两次了,为什么得出的答案却是正确的呢?


代码如下:
  1. class  function1
  2. {
  3.              public static void main(String[] args)
  4.            {
  5.                         int n=2,m=7;
  6.                         n=n^m;
  7.                         m=n^m;
  8.                         n=n^m;
  9.                         System.out.println("n="+n+",m="+m);
  10.         }
  11.         
  12. }
复制代码

作者: 李伟    时间: 2012-6-15 21:09
n=n^m;
m=n^m;//  相当于m=(n^m)^m=n               
n=n^m;//相当于n=(n^m)^n=m
这样m和n的值就互换了


作者: 张_涛    时间: 2012-6-15 21:09
^为异或运算
初值n= 00000010   m= 00000111

第6行:n=n^m=00000101  此时m=00000111 n=00000101
第7行:m=n^m=00000010  此时m=00000010 n=00000101
第8行:n=n^m=00000111  此时m=00000010 n=00000111

最后m=2   n=7
作者: 李伟    时间: 2012-6-15 21:12
(n^m)^n和(m^n)^n是等价的没有先后顺序结果都是m
作者: 邱国    时间: 2012-6-15 21:17
本帖最后由 邱国 于 2012-6-15 21:18 编辑


这个问题试试就知道了 事实就是(n^m)^n = m.


所以经过程序后,n.m发生了置换



作者: 陆鹏    时间: 2012-6-15 21:58
原值为n  m。 变化后的值 n1    m1
n1=n^m
m1=n1^m  --------->m1=n^m^m=n
n=n1^m1 ---------->n=n^m^n  -------n=m^n^n=m   (换下顺序好看而已)
希望这样能看懂。
作者: 王莹    时间: 2012-6-15 22:13
难道这个和数学式中交换律是一样的?可以把异或当成乘法来看?
作者: 陆鹏    时间: 2012-6-15 22:18
王莹 发表于 2012-6-15 22:13
难道这个和数学式中交换律是一样的?可以把异或当成乘法来看?

可以的,不信你随便用两个二进制试试,比如n=101,m=110,怎么换结果都一样。
作者: 吴琼    时间: 2012-6-15 22:43
class  function1
{
             public static void main(String[] args)
           {
                        int n=2,m=7;
                        n=n^m;
                        m=n^m;等价于m=n^m^m即m=n;将2赋给了m此时m=2
                        n=n^m;等价于n=n^m^n即n=m此时n=7
                        System.out.println("n="+n+",m="+m);打印n=7,m=2.
        }
此题需要记住一个原理,一个数被同一个数异或偶数次,值不变.
这是一道面试题,可以不需要第三方变量,将2个数互换.
        
}做
作者: 梁清平    时间: 2012-6-15 22:45
两个变量的值互换在实战中一般是不用这种方法的。。。有问题搞不清楚的时候可以画个图就会清晰很多。。。我画了个图给大家分享。。。三种方式:

^.jpg (1.49 MB, 下载次数: 32)

这是三种互换方式

这是三种互换方式

作者: 郑冬    时间: 2012-6-15 23:29
    Java异或运算的基本法则,只要两个条件同时为真或假,其结果都为假(这里要注意区别Java的与运算---其为真真为真,假假为假);但仅当两条件中一个为真,另一个为假时,结果为真.Java的异或运算还有一个前提那就是它都是以二进制数据为基础进行的运算。也就是在代码中使用到异或运算时,会先将两个条件进行转换,转换成二进制数据后,再进行运算,2对应的二进制数为:00000010;7对应的是:00000111,0<-->0=0;1<-->1=0;0<-->1=1;0<-->0=0
class  function1
{
             public static void main(String[] args)
           {
                        int n=2,m=7;//2对应的二进制数为:00000010;7对应的是:00000111
                        n=n^m;//n=n^m=00000101  此时m=00000111 n=00000101


                        m=n^m;//m=n^m=00000010  此时m=00000010 n=00000101
                        n=n^m;//n=n^m=0111  此时m=00000010 n=00000111
                        System.out.println("n="+n+",m="+m);
        }
}
最后得到n = 7,m=2;

作者: 陆鹏    时间: 2012-6-16 09:59
梁清平 发表于 2012-6-15 22:45
两个变量的值互换在实战中一般是不用这种方法的。。。有问题搞不清楚的时候可以画个图就会清晰很多。。。我 ...

总结得真好呀。
作者: busywhj    时间: 2012-6-16 11:33
(n^m)^n的结果还是m,^运算符合交换律的。放开思想,不要拘泥于一种形式。
作者: 刘笑    时间: 2012-6-16 14:30
异或是不分顺序的,适用于交换律,故(n^m)^n和(m^n)^n是等价的




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