【C】Find two numbers that appear alone in a set of data

1. Problem description

  There are only two numbers in an array that appear once and all other numbers appear twice, try to find those two numbers.

2. Algorithm analysis

  First, the number of elements in the array must be even (ps: if the array elements are odd, the condition " only two numbers appear once, other numbers appear twice " is not satisfied). Secondly, since only two numbers appear once, the two numbers must be different, so the result of the bitwise XOR of these two numbers is not 0. In fact , the result of the bitwise XOR of the entire array is the result of the bitwise XOR of these two different numbers , because the other numbers are canceled out after the pairwise XOR (ps: that is, 0). Since the two numbers are different, one of the two numbers must be different, so try to find the different bits. On the condition that 1 appears on the far right in the result of the bitwise XOR of two different numbers , two sets of data can be filtered out, so as to separate the two different numbers, and finally the elements of each array can be obtained by bitwise XOR respectively. these two different numbers.

3. Algorithm steps

a. Check whether the number of elements is even (ps: if the number of array elements is odd, the condition is not met);

b. Determine whether the value of the entire array element is not 0 by bitwise XOR (ps: if 0 is obtained, it means that all elements in the array appear in pairs);

c. Calculate the decimal number with the rightmost 1 in the result of the bitwise XOR (ps: only this bit is 1, other bits are 0);

d. If the result of bitwise AND c of the elements of the array is equal to c, then bitwise XOR the elements of this new array to get a single number;

e. If the result of a bitwise AND of the array elements is not equal to c, then bitwise XOR the elements of this new array to get a single occurrence of a number.

4. Source code

#define _CRT_SECURE_NO_WARNINGS 1

/*
* Copyright (c) 2018, code farmer from sust
* All rights reserved.
*
* File name: AppearNumTwice.c
* Function: only two numbers appear once in an array,
* All other numbers appear twice, find these two numbers
*
* Current version: V1.0
* Author: sustzc
* Completion date: April 20, 2018 12:13:47
*/

# include <stdio.h>
# include <assert.h>

/*
* Function name: FindOneNum
*
* Function: find out the numbers that appear alone in a set of data
*
* Entry parameters: pArr, len
*
* Export parameter: ret
*
* return type: int
*/

int FindOneNum(int * pArr, int len)
{
	int i = 0;
	int ret = 0 ;

	assert(NULL != pArr);

	for (i=0; i<len; i++)
	{
		ret ^ = pArr [i];
	}

	return ret;
}

/*
* Function name: JudgeRightOne
*
* Function: judge the first occurrence of 1 on the right side of the array
*
* Entry parameters: pArr, len
*
* Export parameter: value
*
* return type: int
*/

int JudgeRightOne(int * pArr, int len)
{
	int value = FindOneNum(pArr, len);

	assert(NULL != pArr);

	//value &= ~(value - 1);
	value &= (-value);

	return value;
}

/*
* Function name: FindTwoNum
*
* Function: find out the numbers that appear alone in a set of data
*
* Entry parameters: pArr, len, first, second
*
* Exit parameter: 0 or 1
*
* return type: int
*/

int FindTwoNum(int * pArr, int len, int * first, int * second)
{
	int i = 0;
	int bit = JudgeRightOne(pArr, len);
	int flag = FindOneNum(pArr, len);

	assert((NULL != pArr) && (NULL != first) && (NULL != second));

	for (i=0; i<len; i++)
	{
		// first occurrence of 1 on the right
		if(((bit == (pArr[i] & bit)) && (0 != flag)))
		{
			*first ^= pArr[i];
		}
		else if (((bit != (pArr[i] & bit)) && (0 != flag)))
			{
				*second ^= pArr[i];
			}
			else
			{
				return 0;
			}
	}

	return 1;
}

/*
* Function name: OutputArray
*
* Function: output array elements
*
* Entry parameters: pArr, len
*
* Exit parameter: void
*
* Return type: void
*/

void OutputArray(int * pArr, int len)
{
	int i = 0;

	assert(NULL != pArr);

	for (i=0; i<len; i++)
	{
		printf("%d ", pArr[i]);
	}

	printf("\n");

	return;
}

int main(void)
{
	int first = 0;
	int second = 0;
	int arr[] = {1,4,1,6,8,6};
	int len = sizeof(arr) / sizeof(int);

	if (0 == (len%2))
	{
		printf("Array elements are:\n");
		OutputArray(arr, len);

		printf("The number that appears twice alone is:\n");

		if (!FindTwoNum(arr, len, &first, &second))
		{
			printf("Not found!\n");
		}
		else
		{
			printf("%d %d\n", first, second);
		}
	}
	else
	{
		printf("Array elements are:\n");
		OutputArray(arr, len);
		printf("Not found, please check the number of arrays!\n");
	}

	return 0;
}

5. Output results




Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324760794&siteId=291194637