题目:
给一组数,只有两个数只出现了一次,其他所有数都是成对出现的。怎么找出这两个数。编写函数实现。
题目分析:
上次介绍了,对于一组数中只有一个数只出现一次,其他所有数都是成对出现的,我们采用了对全部数组元素进行异或,但是对于找出两个出现一次的数应该怎么解决呢?先对所有的元素进行异或,则结果为两个出现一次的数的异或结果,然后将结果转换为二进制,找出二进制数中的第一个1,然后根据这个1的判断条件进行分组,分为两组,分别对两个组的元素进行全部异或,则就找出两个不同的数。
例如:数组中的元素为下面这些数:
0000 --0
0000 --0
0001 --1
0001 --1
0010 --2
0011 --3
0011 --3
0100 --4
0100 --4
0101 --5
全部元素异或的结果为:0111 以最后面的1为条件,分为第一组(1、1、3、3、5)和第二组(0、0、2、4、4),分别对两组元素进行全部异或。
下面是具体的程序:
#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <stdlib.h> int find_get(int num) //转换为二进制 { int get = 0; while(num) { if(num % 2 == 1) //返回转换的二进制中出现第一个的位数 { return get; } get++; num = num / 2; } return -1; } void find_num(int arr[], int ret, int *p, int *q) { int i = 0; int find = 0; int pos = 0; for(i = 0; i < ret; i++) //将所有的数字异或,得到find { find ^= arr[i]; } pos = find_get(find); for(i = 0; i < ret; i++) { if (1 & (arr[i] >> pos)) { *p ^= arr[i]; } else { *q ^= arr[i]; } } } int main() { int arr[] = {1,1,2,2,3,3,4,5}; int ret = sizeof(arr) / sizeof(arr[0]); int find = 0; int num1 = 0; int num2 = 0; printf("输出只出现一次的数字:\n"); find_num(arr, ret, &num1, &num2); printf("%d %d", num1, num2); system("pause"); return 0; }
本文出自 “无心的执着” 博客,转载请与作者联系!