- 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
题目描述:
-
输入:
-
每个测试案例包括两行:第一行包含一个整数n,表示数组大小。2<=n <= 10^6。第二行包含n个整数,表示数组元素,元素均为int。
-
输出:
- 对应每个测试案例,输出数组中只出现一次的两个数。输出的数字从小到大的顺序。
-
样例输入:
-
8 2 4 3 6 3 2 5 5
-
样例输出:
-
4 6
分析
借鉴 《编程之美》
利用位运算
1. 相同的数按位异或得到0
2. 0和任意数异或得到该数本身
3. 如果一个数序列,一个数出现一次,其它数出现两次,所有数按位异或结果为 该出现一次的数
4. 题目要求的是两个不同的数,这两个数异或后肯定有一位为1,找出这个位,按照该位为1或0进行分类
5. 快速找到一个数最低位1的方法 num&(~num+1)
// test1351new.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
//
void findSinlge(int n){
int *nums = new int[n];
int i = 0;
int num = 0;
int andr = 0;
while(i<n){
std::cin>>num;
andr^=num;
nums[i] = num;
i++;
}
andr = andr &(~andr+1);
i = 0;
int num1=0;
int num2=0;
while(i<n){
if(nums[i]&andr)
num1^=nums[i];
else
num2^=nums[i];
i++;
}
if(num1<num2)
std::cout<<num1<<" "<<num2<<std::endl;
else
std::cout<<num2<<" "<<num1<<std::endl;
}
void test1351(){
int n ;
while(std::cin>>n){
findSinlge(n);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
test1351();
return 0;
}