题目描述:
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次,找出那个只出现了一次的元素。
思绪
- 使用位运算
- 两次异或为 0
代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#define SIZE(a) (sizeof(a) / sizeof(a[0]))
int main(){
int a[] = { 1, 5, 8, 2, 6, 4, 2, 8, 5, 1, 4 };
int i, res = 0;
for (i = 0; i < SIZE(a); i++){
res ^= a[i];//位运算
}
printf("%d\n", res);
system("pause");
return 0;
}
代码生成图:
题目描述:
一个数组中只有两个数字是出现一次, 其他所有数字都出现了两次。找出这两个只出现一次的数字。
思绪
- 用位运算,找出数组只出现一次的两个数字(10 ,12) 异或后得到的数字(6)
- 找出是1(按位寻找)的最低位,将他们分为两组数
- 再次对这两组数用位运算,分别找出两个数组只出现一次的数字(10, 12)
代码如下:
#include<stdio.h>
#include<stdlib.h>
void findNum(int * src, int n, int * pnum1, int * pnum2){
int i, pos;
int sum = 0;
int num1 = 0, num2 = 0;
//用位运算,找到数组只出现一次的两个数字异或后得到的数字
for (i = 0; i < n; i++){
sum ^= src[i];
}
//判断是1(按位寻找)的最低位
for (pos = 0; !(sum & (1 << pos)); pos++){
//不需要循环体
}
//再次对这两组数用位运算,分别找到两个数组只出现一次的数字(10,12)
for (i = 0; i < n; i++){
if (src[i] & (1 << pos)){
num1 ^= src[i];
}
else{
num2 ^= src[i];
}
}
*pnum1 = num1;
*pnum2 = num2;
}
int main(){
int arr[10] = { 2, 6, 8, 3, 10, 3, 2, 12, 8, 6 };
int num1, num2;
findNum(arr, sizeof(arr) / sizeof(arr[0]), &num1, &num2);
printf("%d %d\n", num1, num2);
system("pause");
return 0;
}
代码生成图: