39数组中只出现一次的数字+判断的时候一定加上括号,&的优先级低于!=

题目描述

一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
 
 
思路:记住位运算的基本操作,与或非,异或,异或是两个数相同则为0,不同为1,理解为加法运算。一定记住。
还有就是将计算机表示位数定为32位或者64位,这样就可以遍历数的每一位,看是否为1.
这一题属于位运算的题目,两个数如果相同那么异或运算就为0,将一个变量初始化为0,再与其他数进行异或,不会改变结果,记住一定要记住异或是加法运算。
第一遍全部异或后,得到一个数flag,因为flag一定是两个不同的数异或得到的,那么flag等于1的那一位一定可以将这两个数分开,那么我们再用一次异或就分别找到了这两个数。
这题需要注意的是&的优先级比!=低,自己写的时候flag & bitflag != 0,导致想运算后面的!=,程序总是报错,一定要将判断条件加上括号,已经错了几次了。
 
 
记住:位运算就一个非常重要的公式,flag &(flag - 1),会将flag最后一位1去掉,一次flag - flag & (flag - 1)就是最后一个1,比如flag= 3,位表示位0110, flag & (flag - 1)=0100,减去之后0010.
class Solution {
public:
    void FindNumsAppearOnce(vector<int> data,int *num1,int *num2) {
        int flag = 0;
        for(int i = 0;i < data.size();++i){
            flag ^= data[i];
        }
        int bitflag = 1;
        bitflag = flag - (flag & (flag - 1));
        int left = 0,right = 0;        
        for(int i = 0;i < data.size();++i){
            if((data[i] & bitflag) != 0){
                 left ^= data[i];               
            }
            else{
                right ^= data[i];
            }
        }
        *num1 = left;
        *num2 = right;
    }
};

下面的循环就low了,不好,不需要看了。

 
 
class Solution {
public:
    void FindNumsAppearOnce(vector<int> data,int *num1,int *num2) {
        int flag = 0;
        for(int i = 0;i < data.size();++i){
            flag ^= data[i];
        }
        int bitflag = 1;
        int time = 32;
        while(time--){
            if((flag & bitflag) != 0){
                break;
            }
            bitflag = bitflag << 1;
        }
        int left = 0,right = 0;        
        for(int i = 0;i < data.size();++i){
            if((data[i] & bitflag) != 0){
                 left ^= data[i];               
            }
            else{
                right ^= data[i];
            }
        }
        *num1 = left;
        *num2 = right;
    }
};

 

posted @ 2018-01-04 22:16  zqlucky  阅读(224)  评论(0编辑  收藏  举报