数组中数字出现的次数
题目1:数组中只出现1次的2个数字。
一个整形数组中除2个数字之外,其他数字都出现了2次。请找出这2个数字。
思路:任何一个数字异或它自己都等于0。如果异或整个数组,得到的结果就是数组中唯一出现一次的数字。根据这个思路,我们可以将本题的数组拆分成2个。
数组A:2个相同数字+唯一出现1次的数字。
数组B:2个相同数字+唯一出现1次的另一个数字。
如何拆分数组?
我们异或整个数组得到的结果就是该数组中唯一的2个只出现1次的数字的异或结果,这个结果非0,那么二进制中一定有1位不等于0。
我们根据这位不等于0将数组拆分成2部分,再单独异或得到的2个子数组。
参考代码:
root@gt:/home/git/Code# ./a.out _2jin:2 find1index:1
data:1->1
data:2->0
data:1->1
data:3->1
data:1->1
data:1->1
data:2->0
data:2->0
6 4
root@gt:/home/git/Code# cat find2.c #include <stdio.h> int find1index(int _2jin)
{
int res = 0;
int num = _2jin;
while((num & 1) == 0)
{
++res;
num = num >> 1;
}
printf("_2jin:%d\tfind1index:%d\n",_2jin,res);
return res;
}
int isbit1(int data,int index)
{
int res = 0;
data = data >> index;
if(data & 1 != 0)
{
res = 1;
printf("\tdata:%d->%d\n",data,res);
}
else
printf("data:%d->%d\n",data,res);
return res;
}
void find2(int* pdata,int len,int* num1,int* num2)
{
if(pdata == NULL || len <= 0)
return;
int _2jin = 0;
for(int i = 0;i < len;++i)
_2jin ^= pdata[i];
int index = find1index(_2jin);
*num1 = *num2 = 0;
for(int i = 0;i < len;++i)
{
if(isbit1(pdata[i],index))
*num1 ^= pdata[i];
else
*num2 ^= pdata[i];
}
}
int main()
{
int pdata[] = {2,4,3,6,3,2,5,5};
int num1;
int num2;
find2(pdata,sizeof(pdata)/sizeof(int),&num1,&num2);
printf("%d\t%d\n",num1,num2);
return 0;
}
题目2:数组中唯一出现1次的数字。
在一个数组中除了一个数字出现1次,其他数字都出现3次。
思路:我们把数组中所有数字的二进制表示的的每一位加起来,如果某一位的和能被3整除,那么那个只出现1次的数字的二进制表示中该位为0.
参考代码:
root@gt:/home/git/Code# ./a.out 0 i:0 temp = 1
1 i:1 temp = 2
1 i:2 temp = 4
0 i:3 temp = 8
0 i:4 temp = 16
0 i:5 temp = 32
0 i:6 temp = 64
0 i:7 temp = 128
0 i:8 temp = 256
0 i:9 temp = 512
0 i:10 temp = 1024
0 i:11 temp = 2048
0 i:12 temp = 4096
0 i:13 temp = 8192
0 i:14 temp = 16384
0 i:15 temp = 32768
0 i:16 temp = 65536
0 i:17 temp = 131072
0 i:18 temp = 262144
0 i:19 temp = 524288
0 i:20 temp = 1048576
0 i:21 temp = 2097152
0 i:22 temp = 4194304
0 i:23 temp = 8388608
0 i:24 temp = 16777216
0 i:25 temp = 33554432
0 i:26 temp = 67108864
0 i:27 temp = 134217728
0 i:28 temp = 268435456
0 i:29 temp = 536870912
0 i:30 temp = 1073741824
0 i:31 temp = -2147483648
6
root@gt:/home/git/Code# cat find1.c #include <stdio.h>
int find1(int* num,int len)
{
if(num == NULL || len <= 0)
return 0;
int bitSum[32] = {0};
for(int i = 0;i < len;++i)
{
int bitMask = 1;
for(int j = 0;j < 32;++j)
{
int bit = num[i] & bitMask;
if(bit != 0)
++bitSum[j];
bitMask = bitMask << 1;
}
}
unsigned int res = 0;
unsigned int temp = 0;
for(int i = 0;i < 32;++i)
{
printf("%d ",bitSum[i] % 3);
temp = (unsigned int)1 << i;
printf("i:%d\ttemp = %d\n",i,temp);
if(bitSum[i] % 3 != 0)
res += temp;
}
return res;
}
int main()
{
int num[] = {1,1,2,2,3,3,4,4,5,5,6,5,4,3,2,1};
int res = find1(num,sizeof(num)/sizeof(int));
printf("\n%d\n",res);
return 0;
}