zoukankan      html  css  js  c++  java
  • 异或

    参考:http://blog.csdn.net/u012050154/article/details/51957530

    Q:给出M个正整数,其中M-1个出现了偶数次,1一个出现了奇数次,找出这个数。

         被问到这个问题的时候,我说,把这M各数存在哈希表中,就可以找到那个出现奇数次的数了。然而,这并不是一个好的解法,面试官提示异或。(以下是摘自网络的知识)

         1.按位与(&)【有0则0】

    运算规则:0&0=0;0&1=0;1&0=0;1&1=1;

    用途:

    (1)清零。如果想将一个单元清零,只需与一个各位都为0的数值相与即可。

    (2)取出一个数的指定位。与上 一个指定位为1,其余位为0的数值即可。

    例:设x=11101100,取x的低四位。令x&00001111=00001100

         2.按位或(|)【有1则1】

    运算规则:0|0=0;0|1=1;1|0=1;1|1=1;

    用途:

    (1)常用来对某些位置1。或上 一个指定位为1,其余位为0的数值即可。

    例:设x=11101100,将x的低四位置1。令x|00001111=11101111

         3.异或(^)【同0异1】

    运算规则:0^0=0;0^1=1;1^0=1;1^1=0;

    用途:

    (1)使特定位翻转,异或上 一个要翻转位数为1,其余位为0的数值即可。

    例:设x=11101100,将x的低四位翻转。令x^00001111=11100011

    (2)与0异或,保留原值。

    (3)基于异或运算,不引用新变量,交换两个变量的值

    a=a^b;b=a^b;a=a^b(基于加减法还有:a=a+b;b=a-b;a=a-b)

    所以,该编程题的解法是:

    public class FindOdd {
        public static void main(String[] args) {
            int[]a={1,1,4,4,4,5,5};
            for(int i=1;i<a.length;i++){
                a[0]=a[0]^a[i];
            }
            System.out.println(a[0]);
        }
    }

     Q2:找出一串数中出现了奇数次的两个数。

    思路:

    这串数中的所有数字异或,结果必定是出现奇数次的那两个数异或的值,并且不为0,记为resExclusiveOR;

    找出resExclusiveOR的第一个为1的那个位,记为indexOf1,将数组中indexOf1位为1的数分为一组num1,indexOf1位为0的数分为一组num2;

    分别对num1、num2中的数做异或,其结果就是要找的那两个数。(附代码,源自网络)

    public class FindOdd {
        static void findOnce(int[]data,int length){
            int num1=0;
            int num2=0;
            if(length<2)
                return;
            int resExclusiveOR = data[0];
            for(int i=1;i<length;i++){
                resExclusiveOR^=data[i];
            }
            int indexOf1 = findFirstBitIs1(resExclusiveOR);
            for(int i=0;i<length;i++){
                if(isBit1(data[i],indexOf1)){
                    num1=num1^data[i];
                }else{
                    num2=num2^data[i];
                }
            }
            System.out.println(num1+" "+num2);
        }
        static int findFirstBitIs1(int r){
            int indexBit=0;
            while((r&1)==0&&(indexBit<32)){
                r=r>>1;
                indexBit++;
            }
            return indexBit;
        }
        static boolean isBit1(int num,int index){
            if(((num>>index)&1)==1)
                return true;
            else
                return false;
        }
        public static void main(String[] args) {
            int[]arr={1,4,4,1,6,6,6,7,8,8,8,7};
            findOnce(arr,12);
        }
    }

     17.11.9

    (1)计算某个正整数中二进制表示中1的个数

    方法1:

    public static void main(String[] args) {
            int n=7;
            int count=0;
            while(n>0) {
                if((n&1)==1) {
                    count++;
                }
                n=n>>1;
            }
            System.out.println(count);
        }

    但是该解法存在一个问题:

    (补充:

    右移:00001010>>2=00000010;10001010>>3=11110001

    左移:00001010<<2=00101000;10001010<<3=01010000)

    方法 2:

     private static int countBit(int num){
            int count = 0;
            for(; num > 0; count++)
            {
                num &= (num - 1);
            }
            return count;
        }

    参考:

    http://www.cnblogs.com/hapjin/p/5839797.html

    http://www.cnblogs.com/graphics/archive/2010/06/21/1752421.html

    (2)判断某个数的第 i 位是0还是1

    private static boolean getBit(int num,int b) {
            return ((num & (1 << b)) != 0);
        }
  • 相关阅读:
    自考新教材-p282
    p281
    自考新教材-p279_2
    用jmap分析java程序
    用jstack工具分析java程序
    java应用maven插件动态生成webservice代码
    Java对信号的处理
    【OracleDB】 01 概述和基本操作
    【Oracle】Windows-19C 下载安装
    【Hibernate】06 查询API
  • 原文地址:https://www.cnblogs.com/alatar16/p/8994738.html
Copyright © 2011-2022 走看看