“单身狗”问题

文章目录

这里将主要运用异或运算符(^)解决这一类问题

该运算符的规则是:

将参加运算的两个数进行二进制的转换,再对照位进行运算,两个二进制同号,则结果为0;异号,则结果为1

根据这一规则,可以总结出以下结论

  1. 0异或任何数,其结果等于任何数
  2. 1异或任何数,其结果等于任何数取反
  3. 任何数异或自己,其结果为零

初级

一个整型数组里除了一个数字之外,其他的数字都出现了两次。请写程序找出这个只出现一次的数字。例如数组
为{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;
}

👁代码效果:

在这里插入图片描述

通过这个例题,我们可以充分感受到运算符的神奇,只有通过不断地练习,我们方才能够熟练的运用这些。

  • 11
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

富春山居_ZYY(已黑化)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值