一组数中,只有两个数只出现了奇数次,其他所有数都是成对出现的,请找出那两个数

先看一个简单的,一组数中,只有一个数只出现了奇次,其他所有数都是成对出现的,找出出现奇次数的数。对于这个题,我们只需对所有数及逆行异或即可。理论公式:

a⊕b=b⊕a

a⊕0=a

a⊕b⊕b=a

a⊕(b⊕c)=(a⊕b)⊕c

代码:

#include <stdio.h>
#include <stdlib.h>

int main()
{
	int arr[] = { 1, 2, 3, 4, 1, 2, 3 };
	int ret = 0;
	int len = sizeof(arr) / sizeof(arr[0]);
	for (int i = 0; i < len; i++)
	{
		ret ^= arr[i];
	}
	printf("出现奇数次的数为:> %d\n", ret);
	system("pause");
	return 0;
}

现看比较难的,一组数中,只有两个数只出现了奇次,其他所有数都是成对出现的,找出出现奇次数的数。通过上面的简单的例子,我们可以知道,只要我们把两个分开,分为两组数,再分别利用异或,就可以得那两个数。

现在我们看如何将一组数分为每一组数都只有一个数出现过一次的两组数:首先我们对所有数进行异或,那么得到的就是两个出现奇次的那两个数的异或,比如{ 1, 2, 3, 4, 1, 2, 7, 3 },就得到7⊕4,这个数肯定不为0,我们找出这个数的二进制数的最右边的1(设最右边的1在第inter位),然后找出数组的每个元素的第inter位,并判断此位是1还是0,是1的为一组,是0的为一组,这样就分好了组,再利用上面的例子,就可得到出现奇数次的那两个数。

#include <stdio.h>
#include <stdlib.h>

int main()
{
	int arr[] = { 1, 2, 3, 4, 1, 2, 7, 3 };
	int len = sizeof(arr) / sizeof(arr[0]);
	int ret = 0;
	int inter = 0;
	int retA = 0;
	int retB = 0;
	for (int i = 0; i < len; i++)
	{
		ret ^= arr[i];
	}
	/*找ret最右边的1*/
	inter = ret - (ret&(ret - 1));
	for (int i = 0; i < len; i++)
	{
		int a = (arr[i] >> (inter - 1)) % 2;   //取出arr[i]的第inter位
		if (a == 0)
		{
			retA ^= arr[i];
		}
		else
		{
			retB ^= arr[i];
		}
	}
	printf("出现奇数次的两个数为:> %d,%d\n", retA, retB);
	system("pause");
	return 0;
}
时间: 2024-10-20 13:12:59

一组数中,只有两个数只出现了奇数次,其他所有数都是成对出现的,请找出那两个数的相关文章

【c语言】 给一组数,有两个数只出现了一次,其他所有数都是成对出现的。找出这两个数

// 给一组数,有两个数只出现了一次,其他所有数都是成对出现的.找出这两个数. #include <stdio.h> void find_two_diff(int arr[], int len, int *num1, int *num2)//设置两个返回型参数 { int i = 0; int ret = 0; int pos = 1; *num1 = 0; *num2 = 0; for (i = 0; i < len; ++i) { ret ^= arr[i]; } // 找出ret中

一个组数中只有两个数只出现了一次,其他所有数都是成对出现的,找出这两个数

原题:给一组数,只有两个数只出现了一次,其他所有数都是成对出现的.怎么找出这两个数. 编写函数实现. 对于一组数中只有一个数只出现一次,其他所有数都是成对出现的,我们采用了对全部数组元素进行异或,经过分析发现异或全部数组的数所得到的数为整个数组中两个只出现一次数异或的结果先对所有的元素进行异或.可以通过将结果转换为二进制,在移位二进制数中的第一个1,然后根据这个1的判断条件将整个数组分为两组,分别对两个组的元素进行全部异或,则就找出两个不同的数. 例如:数组中的元素为下面这些数: 0000   

【c语言】给一组数,只有一个数只出现了一次,其他所有数都是成对出现的。找出这个数

// 给一组数,只有一个数只出现了一次,其他所有数都是成对出现的.找出这个数 #include <stdio.h> int find_one(int arr[], int len) { int i = 0; int ret = 0; for (; i < len; ++i) { ret ^= arr[i]; } return ret; } int main() { int arr[] = { 1, 2, 3, 4, 1, 2, 3 }; printf("%d\n",

一组数据中只有一个数字出现了一次。其他所有数字都是成对出现的。请找出这个数字。(使用位运算)

#include <stdio.h> int main() {      int arr[5];      int i,j;      int len=sizeof(arr)/sizeof(arr[0]);     //初始化数组      for(i=0;i<len;i++)            {        scanf("%d",&arr[i]);      }     //查找的过程      j=arr[0];     for(i=1;i<

找出一组数中只出现一次的两个数,其他所有数都是成对出现的

题目: 给一组数,只有两个数只出现了一次,其他所有数都是成对出现的.怎么找出这两个数.编写函数实现. 题目分析: 上次介绍了,对于一组数中只有一个数只出现一次,其他所有数都是成对出现的,我们采用了对全部数组元素进行异或,但是对于找出两个出现一次的数应该怎么解决呢?先对所有的元素进行异或,则结果为两个出现一次的数的异或结果,然后将结果转换为二进制,找出二进制数中的第一个1,然后根据这个1的判断条件进行分组,分为两组,分别对两个组的元素进行全部异或,则就找出两个不同的数. 例如:数组中的元素为下面这

【C语言】给一组组数,只有两个数只出现了一次,其他所有数都是成对出现的,找出这两个数。

//给?组组数,只有两个数只出现了一次,其他所有数都是成对出现的,找出这两个数. #include <stdio.h> int find_one_pos(int num) //找一个为为1的位置 { int n = 0; while(num) { if (num & 1 == 1) break; else { n++; num >>= 1; } } return n; } void find_two_differ(int arr[], int len, int *num1,

一个数组中,一些数出现2次,只有两个数各出现一次,找出这两个数

https://leetcode.com/problems/single-number-iii/ 初次看到这题时,就想到用异或,但只能找出这两个数异或的结果,不能找出这两个数.最后我用快排过了,然后去看了看人家的思路.看来还是得仔细分析其中的隐藏信息啊.比如:从这两个数异或后的结果值可以看出,从低位开始到某一位不为0时,一定是这两个数的二进制位在此时不同了(从低位开始一定可以找到一个不为0的,因为这两个数不同).这个位可以用树状数组的lowbit方法将异或值与此值的负数进行异或求出.然后将这个数

返回一组数中最大的K个(JS实现)

第一次见到类似题目大约是在六年前吧.一道简单的ACM题,自己费半天劲用土方法得出结果,跟别人用堆排序求得结果的时间效率相差数倍,使得笔者第一次深切领略到算法的魅力.六年之后,再一次被人问到这道题,"堆排序"瞬间蹦入脑海. 不同的是,当时玩C,现在玩Java和JS,最熟的就是JS了,于是用JS把算法写了出来: function topKMaxOfArr(k, arr){ function swap(a, b){ var t = arr[a]; arr[a] = arr[b]; arr[b

Jsの数组练习-求一组数中的最大值和最小值,以及所在位置

要求:求一组数中的最大值和最小值,以及所在位置 代码实现: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv=&