题目:在一个数组中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。
解题思路:
如果一个数字出现三次,那么这个数表示的二进制的每一位的和都能被3整除。把不能整除的数加起来就是那个只出现一次的数字。
如:在数组{8,6,7,8,8,6,6}中,3个8的二进制的每一位的和为:1000+ 1000+ 1000 = 3000,3个6的二进制的每一位的和为:0110 + 0110 + 0110 = 0330,7的二进制为0111,那么整个数组的二进制的和为:3441。用它除以(%)3余0111,即为7。
程序为:
#include<stdio.h>
#include<stdlib.h>
int FindOnlyOneNum(int arr[], int len)
{
//处理异常情况
if (arr == NULL || len <= 0)
{
return -1;
}
//定义一个数组存放数组各元素各位上的值的和
int bitarr[32] = { 0 };
//遍历整个数组,计算数组各元素在各位上的和
for (int i = 0; i < len; i++)
{
int bitmask = 1;//位掩码
for (int j = 31; j >= 0; j--)
{
int bit = arr[i] & bitmask;
if (bit != 0)
{
bitarr[j] += 1;
}
bitmask = bitmask << 1;
}
}
//用数组各元素各位上的和除以3,记录不被3整除的数
int result = 0;
for (int k = 0; k < 32; k++)
{
result = result << 1;
result += bitarr[k] % 3;
}
return result;
}
int main()
{
int arr[] = { 8, 6, 7, 8, 8, 6, 6 };
int len = sizeof(arr) / sizeof(arr[0]);
printf("数组的元素为:");
for (int i = 0; i < len; i++)
{
printf("% d", arr[i]);
}
printf("\n");
int ret = FindOnlyOneNum(arr, len);
printf("数组中只出现一次的元素是:% d\n", ret);
system("pause");
return 0;
}
运行的结果为: