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

来源:互联网 发布:金山软件港股行情 编辑:程序博客网 时间:2024/04/28 13:18

     按照昨天的推导过程,今天把代码贴上:顺便提一下原文中(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 DEBUGusing 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 DEBUGcout<<"diff_bit: "<<diff_bit<<endl;#endif     diff_bit ^= makeOnlyLowestBit1On(three_number_or^*iter);}diff_bit = makeOnlyLowestBit1On(diff_bit);#ifdef DEBUGcout<<"diff_bit: "<<diff_bit<<endl;#endifassert(diff_bit!=0);//cout<<"diff_bit:"<<diff_bit<<endl;//find first numberint 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 DEBUGcout<<"iter: "<<*iter<<endl;#endiffirst_number ^= *iter;}}result.push_back(first_number);//find the other two numbersint 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 DEBUGcopy(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;}


0 0