数组中三个只出现一次的数字2

     按照昨天的推导过程,今天把代码贴上:顺便提一下原文中(http://zhedahht.blog.163.com/blog/static/25411174201283084246412/)代码本身的算法却没错,按照代码本身的解法,上文蓝色字体部分(那么x^a、x^b、x^c的结果中,有一个或者三个数字的第m位是1),应改为那么f(x^a)、f(x^b)、f(x^c)的结果中,有一个或者三个数字的第m位是1同样的容易证得f(x^a)、f(x^b)、f(x^c)不可能三个都为1,所以f(x^a)、f(x^b)、f(x^c)只有其中一个为1原文的代码正是基于这个结果写的。一下贴出按照昨天证明过程写的代码:

   

#include <iostream></span>
#include <vector>
#include <cassert>
#include <iterator>
#include <algorithm>

//#define DEBUG


using namespace std;

inline int makeOnlyLowestBit1On(const int n)
{
	if(n==0)
		return 0;
	int result = 1;
	for(;(result&n)==0;result<<=1)
		;
	return result;
}
inline bool isFixBitSame(int n_power_2,int number1,int number2)
{
	return (n_power_2&number1) == (n_power_2&number2);
}
void  findOnlyAppearOnceThreeNumber(const vector<int>& data_array,vector<int>&result)
{
	int   three_number_or=0;
	
	//x = a^b^c   (x=three_number_xor)
	for(vector<int>::const_iterator iter = data_array.begin();iter!=data_array.end();++iter)
		three_number_or ^= *iter;
	
	//f(x^a)^f(x^b)^(x^c)  
	int diff_bit = 0;
	for(vector<int>::const_iterator iter = data_array.begin();iter!=data_array.end();++iter){
#ifdef DEBUG
		cout<<"diff_bit: "<<diff_bit<<endl;
#endif
	     diff_bit ^= makeOnlyLowestBit1On(three_number_or^*iter);
	}
	diff_bit = makeOnlyLowestBit1On(diff_bit);
#ifdef DEBUG
	cout<<"diff_bit: "<<diff_bit<<endl;
#endif
	assert(diff_bit!=0);
	
	//cout<<"diff_bit:"<<diff_bit<<endl;
	//find first number
	int first_number=0;
	for(vector<int>::const_iterator iter = data_array.begin();iter!=data_array.end();++iter){
		if(isFixBitSame(diff_bit,three_number_or,*iter)){
#ifdef DEBUG
			cout<<"iter: "<<*iter<<endl;
#endif
			first_number ^= *iter;
		}
	}
	result.push_back(first_number);

	//find the other two numbers
	int two_number_first_diff_bit = makeOnlyLowestBit1On(three_number_or^first_number);
	int second_number = 0;
	for(vector<int>::const_iterator iter = data_array.begin();iter!=data_array.end();++iter){
		if((*iter!=first_number)&&((*iter&two_number_first_diff_bit)>0))
			second_number ^= *iter;
	}
	result.push_back(second_number);
	result.push_back(three_number_or^first_number^second_number);
	
#ifdef DEBUG
	copy(result.begin(),result.end(),std::ostream_iterator<int>(std::cout," "));
	std::cout<<std::endl;
#endif
	
}


int main(int argc,char *argv[])
{
	int case_num;
	vector<int> data,result;
	
	while(cin>>case_num){
		int value;
		for(int i = 0;i<case_num;++i){
			cin>>value;
			data.push_back(value);
		}
		findOnlyAppearOnceThreeNumber(data,result);
		copy(result.begin(),result.end(),std::ostream_iterator<int>(std::cout," "));
		std::cout<<std::endl;
		data.clear();
		result.clear();
			
	}
	return 0;
}

点赞