C语言 两只单身狗问题

本文介绍了一种算法,利用按位异或操作找出数组中只出现一次的两个数字。首先对数组进行异或操作,然后通过位操作找到不同位的数字,最后分类并再次异或,得出结果5和6。
摘要由CSDN通过智能技术生成

 

目录

题目

一、明确思路

二、代码实现

第一步

 第二步

第三步 

三、整体代码

结语

喜欢的话还请多多支持,蟹蟹!

 今天来分享一道题目,找到两只单身狗,在一组数字中找到只出现一次的两个数字,个人感觉还是挺有意思的。

题目

一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。

编写一个函数找出这两个只出现一次的数字。

例如:

有数组的元素是:1,2,3,4,5,1,2,3,4,6

只有5和6只出现1次,要找出5和6.

一、明确思路

    在一堆数字中找到其中只出现一次的两个数字,这里我们就可以想到用按位异或操作符,按照按位异或操作符的原理,出现两次的的数字会在按位异或之后变成0,而0按位异或上任何数字都会得到原数字,把数组中的数字都按位异或一遍,最后会得到两个只出现一次的数字的按位异或的结果。

    得出了两个数字按位异或的结果,接下来就是找出两个数字的不同,我们知道在按位异或时,两个数字的补码(数字在电脑中存储用的就是补码)同一位上的数字相同得到的结果就是1,反之就是0,我们就需要找到这个1的位置(找到其中一个就可以了),将得到的结果按位与上1,1不断地用上左移操作符,直到结果为1,,再将数组的数字根据这个位置是否为1进行分类,再次进行按位异或,得到两个单身狗数字。

二、代码实现

     明确了思路之后,就可以用代码实现了,下面直接上代码加上注释。

第一步

int arr[10] = { 1,2,3,4,5,1,2,3,4,6 };
int i,count;
int sum = 0;
for (i = 0; i < 10; i++)
{
	sum ^= arr[i];  //把所有数字都进行按位异或操作,得到两个单身狗数字的按位异或结果。
}

 第二步

for (i = 0; i < 32; i++)
{
	if (sum & 1 << i)//按位与上1,找到上一步得到的结果中数字哪个位置的数字为1
	{
		count = i;  //记录第几位
		break;
	}
}

第三步 

int dog1=0, dog2=0;
for (i = 0; i < 10; i++)
{
	if (arr[i] & 1 << count) //将数组中这个位上不同的两种数进行分类
		dog1 ^= arr[i];
	else
		dog2 ^= arr[i];  //分类后的数进行按位异或得到两个只出现一次数字
}

三、整体代码

#include<stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,1,2,3,4,6 };
	int i,count;
	int sum = 0;
	for (i = 0; i < 10; i++)
	{
		sum ^= arr[i];
	}
	for (i = 0; i < 32; i++)
	{
		if (sum & 1 << i)
		{
			count = i;
			break;
		}
	}
	int dog1=0, dog2=0;
	for (i = 0; i < 10; i++)
	{
		if (arr[i] & 1 << count)
			dog1 ^= arr[i];
		else
			dog2 ^= arr[i];
	}
	printf("两个单身狗是%d %d", dog1, dog2);
	return 0;
}

结语

    如果觉得写的不错,还请多多点赞、收藏,有什么不对的地方,多多指教,感谢支持。

  • 17
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值