一組の数の中で、2つの数だけ奇数回しか現れません.他のすべての数はペアで現れます.その2つの数を見つけてください.


まず1つの簡単なものを見て、1組の数の中で、1つの数だけ奇次が現れて、その他のすべての数はすべてペアで現れて、奇数が現れた数を見つけます.この問題に対して、私たちはすべての数と逆行異或だけでいいです.理論式:
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
", ret); system("pause"); return 0; }

ここで見ると難しいのは、1組の数のうち、2つの数だけ奇次が現れ、他のすべての数はペアで現れ、奇数が現れた数を見つけることだ.上の簡単な例を通して、私たちが2つを分けて、2つのグループに分けて、またそれぞれ異或を利用すれば、その2つの数を得ることができることを知ることができます.
まず、私たちはすべての数に対して異和を行い、それで得られたのは2つの奇次が現れた2つの数の異和であり、例えば{1,2,3,4,1,2,7,3}であり、7,4,この数は0ではないに違いない.この数のバイナリ数の右端の1(右端の1をinter位とする)を見つけて、配列の各要素のinter位を見つけて、この位が1なのか0なのかを判断して、1のグループで、0のグループで、このようにグループを分けて、上の例を利用して、奇数回現れる2つの数を得ることができます.
#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
", retA, retB); system("pause"); return 0; }