👑个人主页:啊Q闻
🎇收录专栏:《C语言》
🎉道阻且长,行则将至
前言
这篇文章是关于C语言的习题之找单身狗(即从一组数据中找出只出现一次的数字),会涉及到一些位操作符的使用,也是属于位操作符的应用
一、找单身狗1
1.题目与思路分析
题目:在一个整型数组中,只有一个数字出现一次,其他数组都是成对出现的,请找出那个只出现一次的数字。例如:在1 1 2 3 2,找出3
思路:1.按位异或^常用于找不同,相同为0,相异为1。
2. 当两个相同的数字^时,其就会相互抵消,
例如:2^2,其二进制可以写成00000000000000000000000000000010
00000000000000000000000000000010
二者^时,会变成00000000000000000000000000000000 达到相互抵消的效果
3. 利用^的效果,可以达到找出单身狗的效果
2.代码的实现
#include<stdio.h>
int Func(int arr[], int len)
{
int num = 0;
int i = 0;
for (i = 0; i < len; i++)
{
num ^= arr[i];//利用按位异或实现找出只出现一次的数字
}
return num;
}
int main()
{
int arr[10] = { 1,1,2,3,2 };
int len = sizeof(arr) / sizeof(arr[0]);
int ret = Func(arr, len);
printf("单身狗是:%d\n", ret);
return 0;
}
二、找单身狗2
1.题目思路分析
题目:在一个整型数组中,有两个数字出现一次,其他数组都是成对出现的,请找出那个只出现一次的数字。例如:在1,2,3,4,5,6,1,2,3,4中,找出5和6.
思路;1.要想办法将两只单身狗的问题转化为一只单身狗的问题,利用一只单身狗问题的思 路解决两只或多只单身狗问题
2.首先将要找的5和6进行找不同:5的二进制:00000000000000000000000000000101
6的二进制:00000000000000000000000000000110
异或结果: 00000000000000000000000000000011
由异或结果可知,倒数第二位与倒数第一位不同,我们利用倒数第二位的不同将5和6分 为两组,再分别从每组中找出一只单身狗。
3.进行分组:1的二进制:0001(简写)
2的二进制:0010
3的二进制:0011
4的二进制:0100
将倒数第二位为1的分在一组:2,3,6
将倒数第二位为0的分在一组:1,4,5
2.代码的实现
#include<stdio.h>
void FindNum(int arr[20], int len, int* pnum1, int* pnum2)
{
int ret = 0;
int i = 0;
for (i = 0; i < len; i++)
{
ret ^= arr[i];//首先求出5,6二进制异或结果
}
int pos = 0;
for (i = 0; i < 32; i++)//确定ret的二进制中哪一位为1(即找出不同的一位存储在pos中)
{
if ((ret >> i) & 1 == 1)
{
pos = i;
break;
}
}
for (i = 0; i < len; i++)//(按照不同的一位分为两组)
{
if (((arr[i] >> pos) & 1)==1)
{
*pnum1 ^= arr[i];
}
else
{
*pnum2 ^= arr[i];
}
}
printf("%d %d", *pnum1, *pnum2);
}
int main()
{
int arr[] = { 1,2,3,4,5,6,1,2,3,4 };
int len = sizeof(arr) / sizeof(arr[0]);
int num1 = 0;
int num2 = 0;
FindNum(arr, len, &num1, &num2);
return 0;
}
总结
按位异或常用出处理找不同的代码问题,单身狗2的思路可以为我们从一组数据中找出多个单身狗提供思路,希望这篇文章对大家有所帮助。