C language - looking for singles

Finding a single partner is a classic C language programming question. As the name suggests, its purpose is to find unique elements in an array containing repeated integer numbers and individual integer numbers.

Let’s look at a relatively simple example of a single dog:

Only two numbers in an array appear once, and all other numbers appear twice.

Write a function to find these two numbers that appear only once.

For example:

The elements of the array are: 1, 2, 3, 4, 5, 1, 2, 3, 4, 6

Only 5 and 6 appear only once. Find 5 and 6

1. Organize ideas

If there is only one single dog in this array, then you can find this single dog very quickly by directly XORing each element with each other. However, if there are two single dogs in this array, then the XOR method of all elements will not work. , but it also provides us with some ideas. XOR is a very critical entry point

Next, start organizing your thoughts

Repeating elements are: 1 1 2 2 3 3 4 4

There are single dogs: 5 6

Idea 1: You can use several for loops to find duplicate elements, and then eliminate them. The remaining non-duplicate elements are singles.

For this array that only contains 10 elements, this method seems to work. Some handsome guys and beauties think that the worst thing is to use a few more for loops to traverse it a few times. It is simple and crude, as expected of me, haha! !

But, what I mean is that if you encounter an array containing hundreds or thousands of elements, how should you deal with it?

 So Your Excellency, I know you are in a hurry, but please don’t be anxious and listen to what I have to say.

 Since the first idea is not advisable, then we will think of the second idea.

Let’s start by talking about the key point: XOR 

The XOR of other repeated elements is 0, so what is the XOR of 5 and 6?

Convert 5 and 6 to binary (you only need to know the key bits)

5:101

6:110

5^6:011

Hehe, something new will happen when these two singles meet, anyway, it’s not 0

You may say: Well, what next?

It does seem useless, but take a look at the binary of a non-single dog

1:001

2:010

3:011

4:110

Start looking for differences and similarities: starting from the last position, 1 and 3 are both 1, 2 and 4 are both 0

                                                         The last digit of 5 is 1, and the last digit of 6 is 0

Divide 5 and 6 into two different groups

One group: 5 1 1 3 3

Group 2: 6 2 2 4 4

If we XOR the two groups separately, we can find the singles that exist in each group.

Bingo! ! Now that we have the idea, the next step is to structure the code.


2. Architecture code

1. Main function

No matter what, first write a main function

Create another function find_single_dog(arr,sz)

Passing two parameters, arr array name, is actually passing the address of the first element of the array sz, which is the number of elements contained in the array

int main()
{
	int arr[] = { 1,2,1,2,5,3,4,3,4,6 };

	int sz = sizeof(arr) / sizeof(arr[0]);

	find_single_dog(arr, sz);

	return 0;
}

2. Implement the find_single_dog() function independently

1. First use the overall XOR to roughly find singles

2. Calculate which binary number in ret is 1

3. Group into groups and finally find the singles

void find_single_dog(int arr[], int sz)
{
	int single1 = 0;//单身狗1号
	int single2 = 0;//单身狗2号
	int ret = 0;
	int i = 0;
	//1.先整体异或来大概找出单身狗
	for (i = 0;i < sz;i++)
	{
		ret ^= arr[i];//现在 ret = 5^6
	}
	//2.计算ret中二进制第几位为1
	int pos = 0;
	for (i = 0;i < 32;i++)
	{
		if (((ret >> i) & 1) == 1)
		{
			pos = i;//pos纪录位置,同时接受i的值,方便下面分组i的再次使用
			break;
		}
	}

	//3.分组
	for (i = 0;i < sz;i++)
	{
		if (((arr[i] >> pos) & 1) == 0)//找到末位为0的单身狗
		{
			single1 ^= arr[i];//找到第一个单身狗
		}
	}
	//假设第一组得到的单身狗为5
	//ret = 5^6
	//ret^single1 = 5^6^5 = 6^0 =6
	single2 = ret ^ single1;

	printf("%d %d\n", single1, single2);
}

nailed it

Guess you like

Origin blog.csdn.net/cdtu_mid/article/details/131751413