“找单身狗”

目录

前言

一,问题分析

二,具体实现

1.1实现方法

1.2实现代码


前言

如题目所言,这篇文章的内容是在一组数中寻找只出现一次的数,比如 1234123456,在这组数中, 5和6 只出现了一次,所以我们将其称为“单身狗”,那么如何才能从这组数组中找单个出现的元素呢?

其实我们只需要三步即可。

1,首先,对所有数字进行异或,然后得到的两个单独的元素的异或值。

2,对于这个值,其二进制值一定有一位是不同的,我们需要找到该值,暂且将该值所在的位记为 flag。

3,所以我们将这个数组中其他元素分为两组,一组是flag位为1 的,另一组是该位为 0 的,因为这两个单独的元素,被分为两组,所以最后这两组分别进行异或,即可得到这两个单独元素。

------------------------------------正文如下----------------------------------

一,问题分析

首先,我们应该知道,对于一组数,如果其中只有一个单独的数字,那么我们将所有的元素进行异或,然后得到便是那个单独的元素,所以这里我们便用这个原理。将原先的一组数分为两组数,然后分别进行异或,最后得到的便是我们需要的单独出现的那个元素。

二,具体实现

1.1实现方法

首先,对于一组数首先,我们需要将其内容进行异或,然后得到两个单独的元素的异或值 ret 。

然后,我们需要确定该异或值二进制哪一位为 1,为我们后面分组做选择。如下所示,我们用到了右移操作符,在找到哪一位为 1 之后,我们使用 pos 将该位置记下来,而在这里判断哪一位为 1 的时候,又用到了按位与 & 操作符,用以简化操作:

“找单身狗”_第1张图片

第三步,我们对于这组数中的每个元素在右移pos位后,再与 1 按位与,得到数与 1 比较是否相等,然后相等的元素分为一组,不相等的元素分为一组,这两组元素分别进行异或,最后得到的是两个单独的数字。

“找单身狗”_第2张图片

 然后,最后只需要我们打印就可以了,当然这个方法暂时来说,只适用于一组数中有两个单独数字的,如果一组数中单身狗元素比较多,那么这种方法是不适用的。

1.2实现代码

#include
int main()
{
	int arr[] = { 1,2,3,4,5,1,2,3,4,6 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	int ret = 0;
	//1.求出 5^6 的值
	for (i = 0; i < sz; i++)
	{
		ret = ret ^ arr[i];
	}
	//得到 5^6 第几位为 1
	int pos = 0;
	for (i = 0; i < 32; i++)
	{
		if (((ret >> i) & 1) == 1)
			pos = i;
		break;
	}
	//分组
	int m = 0;
	int n = 0;
	for (i = 0; i < sz; i++)
	{
		if (1 == ((arr[i] >> pos) & 1))
		{
			m = m ^ arr[i];
		}
		else
		{
			n = n ^ arr[i];
		}
	}
	printf("%d %d",m,n);
	return 0;
}

好的,那么如果想要实现三个以上单个元素,其实是有比较简单的方法的,就是用两个循环去实现呢,但是那样做的话效率是很低的,但是是可以实现多元素的。如有需要,可以留言哦!

   “找单身狗”_第3张图片

你可能感兴趣的:(c语言,c语言,后端)