这里将主要运用异或运算符(^)解决这一类问题
该运算符的规则是:
将参加运算的两个数进行二进制的转换,再对照位进行运算,两个二进制同号,则结果为0;异号,则结果为1。
根据这一规则,可以总结出以下结论:
- 0异或任何数,其结果等于任何数
- 1异或任何数,其结果等于任何数取反
- 任何数异或自己,其结果为零
初级
一个整型数组里除了一个数字之外,其他的数字都出现了两次。请写程序找出这个只出现一次的数字。例如数组
为{1,3,5,7,1,3,5},找出7。
最佳解法:
根据异或运算符得出的结论,我们可以通过将数组中的所有元素异或在一起,从而找到“单身狗”
✒️代码展示:
#include <stdio.h>
int main()
{
int arr[] = { 1,3,5,7,1,3,5 };
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
int ret = 0;
for(i = 0;i < sz;i ++)
{
ret = ret ^ arr[i];
}
printf("单身狗是%d\n",ret);
return 0;
}
👁代码效果:
进阶
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。例如数组
为{1,3,5,7,1,3,5,9},找出7和9。
在有两条“单身狗”的情况下,如果只是将数组中的所有元素异或结果必不为0,是两个“单身狗”异或在一起的的结果,当然这也是解题的关键步骤之一。
最佳解法:
✒️代码展示:
#include <stdio.h>
void find_num(int str[], int sz, int* x, int* y)
{
int i = 0;
int ret = 0;
//步骤①
for (i = 0; i < sz; i++)
{
ret = ret ^ str[i];
}
int m = 0;
//步骤②
for (i = 0; i < 32; i++)
{
if ((ret >> i) & 1)
{
m = i;
break;
}
}
//步骤③、④、⑤
for (i = 0; i < sz; i++)
{
if ((str[i] >> m) & 1)
{
*x = *x ^ str[i];
}
else
{
*y = *y ^ str[i];
}
}
}
int main()
{
int arr[] = { 1,3,5,7,1,3,5,9 };
int sz = sizeof(arr) / sizeof(arr[0]);
int x = 0, y = 0;
find_num(arr, sz, &x, &y);
printf("%d %d\n", x, y);
return 0;
}
👁代码效果:
通过这个例题,我们可以充分感受到运算符的神奇,只有通过不断地练习,我们方才能够熟练的运用这些。