剑指offer-面试题56_1-数组中只出现一次的两个数字-位运算

/*
题目:
	求数组A中只出现一次的数字,该数组中有2个数字a、b仅出现一次,其余均出现两次
*/
/*
思路:
	两个相同的数字异或为0.
	遍历数组,得到数组中各数字异或后的结果x,结果x=a^b。
	x中肯定存在一位不为0,找到左起第一位为1的位。
	根据该位,将数组分为两拨,再进行异或,得到的结果即为a,b。
*/
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<map>

using namespace std;

void FindNumsAppearOnce(int data[],int length,int &num1,int &num2){
    if(length < 2) return;
    int x = data[0];
    for(int i = 1; i < length; i++){
        x ^= data[i];
    }

    int pos = 0;
    //找到左起第一位为1的位
    while(((x&1) == 0) && (pos < sizeof(int)*8)){
        //x = (x >> 1);
        x = x >> 1;
        pos++;
        cout<<x<<endl;
    }

    //按左起pos位是否位1划分为两组
    for(int i = 0; i < length; i++){
        if(data[i] >> pos & 1){
            num1 ^= data[i];
        }else{
            num2 ^= data[i];
        }
    }
}

int main(){
    int num1 = 0;
    int num2 = 0;
    int data[] = {2,4,3,6,3,2,5,5};
    FindNumsAppearOnce(data,sizeof(data)/sizeof(data[0]),num1,num2);
    cout<<num1<<" "<<num2;
}

   

原文地址:https://www.cnblogs.com/buaaZhhx/p/12098172.html