一、一个数字出现一次,其余数字出现两次ios
两个相同的数异或为0,因此将数组里的全部数依次异或,获得的结果就是只出现一次的数。windows
#include <iostream> using namespace std; int main() { int a[]={3,6,2,3,2,5,5}; int num=0; for(int i=0;i<7;i++) { num^=a[i]; } cout<<num<<endl; return 0; }
二、一个数字出现一次,其余数字出现N次数组
经过观察法,发现若是数字出现了n次,那么每一bit位之和能够被n整除。spa
#include <iostream> #include <string> using namespace std; int FindNumber(int a[], int n, int m) { int bits[32]; int i, j; // 累加数组中全部数字的二进制位 memset(bits, 0, 32 * sizeof(int)); for (i = 0; i < n; i++) for (j = 0; j < 32; j++) bits[j] += ((a[i] >> j) & 1); // 若是某位上的结果不能被整除,则确定目标数字在这一位上为 int result = 0; for (j = 0; j < 32; j++) if (bits[j] % m != 0) result += (1 << j); return result; } int main() { int a[] = {2, 3, 1, 2, 3, 4, 1, 2, 3, 1}; //3表明其余数字出现3次 cout<<FindNumber(a, 10, 3)<<endl; return 0; }
三、两个数字出现一次,其余数字出现两次.net
和1的原理差很少,先是分别异或,获得结果,确定不为0。找到结果1所在的位置x,将原数组分为两部分,第一部分是x为1的数的集合,第二部分是x为0的数的集合。而后分别对这两个数组异或,获得这两个出现一次的数。code
#include <iostream> #include <string> using namespace std; unsigned int FindFirstBitIs1(int num) { int indexBit=0; while(((num&1)==0)&&(indexBit<8*sizeof(int))) { num=num>>1; ++indexBit; } return indexBit; } bool IsBit1(int num,unsigned int indexBit) { num=num>>indexBit; return (num&1); } void FindNumsAppearance(int data[],int length,int *num1,int *num2) { if (data==NULL||length<2) { return; } int resultExclusiveOR=0; for (int i=0;i<length;i++) { resultExclusiveOR^=data[i]; } unsigned int indexof1=FindFirstBitIs1(resultExclusiveOR); *num1=*num2=0; for (int j=0;j<length;j++) { if (IsBit1(data[j],indexof1)) { *num1^=data[j]; } else { *num2^=data[j]; } } } int main() { int a[]={4,3,6,3,2,5,5}; int temp1,temp2; FindNumsAppearance(a,7,&temp1,&temp2); cout<<temp1<<"\t"<<temp2<<endl; return 0; }
参考:blog
http://blog.csdn.net/morewindows/article/details/12684497get