第一周

题目要求:

一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字

看到有同学做了“选取奇数个数的数字”的题目,但是题目为
“一个整型数组里除了一个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字”
可以采用排序的方法求解,让数字成对出现,但是排序的算法最优时间复杂度是 O(nlog2n),也可以采用异或求解,利用异或的方法,可以让相同的两个数字相互异或消除,达到求解目的。
例:a[100] = {7,1,2,3,1,2,3,4,4}

#include "stdio.h"

int number(int a[], int n) {
    int i;
    int result = 0;
    for (i = 0; i

但是如果结果有两个只出现一次的数字时,又该如何求解?
例:a[100] = {7,6,1,2,3,1,2,3,4,4}
结果会出现7和6的位相与后的结果 1,而不是7和6。

做题思路:

按照正常思路最终结果是求出a^b的值,为了求那两个奇数个的数,可以通过a = (a^b) ^ b 和 b = (a^b) ^ a来求解a和b, (a ^ b)已知,剩下的就是通过(a ^ b)想办法求出a和b的数字了。
①:求(a ^ b)
②:利用(a ^ b)求a,b
例中数组{7,6,1,2,3,1,2,3,4,4}求得的(a ^ b)为 7^6,二进制表示为0111和0110,所以(a ^ b)的结果会求得0001,然后我们要通过0001来分析。
首先出现位为1的可能就是位不相等异或出来的,可以将数组分为两个子数组,我们把原数组分成了两个子数组,每个子数组都包含一个只出现一次的数字,而其他数字都出现两次。
如:a[100] = {7,6,1,2,3,1,2,3,4,4} 可变成{0111,0110,0001,0010,0011,0001,0010,0011,0100,0100}
分成两个子数组分别为a = {, 000,001,000,001}(通过(a ^ b)= 0001获得所有结尾为的数)和b = {,0010,0010,0100,0100},将子数组内元素相异或,即求得a和b

#include "stdio.h"
//获得(a ^ b)上的第一个位为1的位置
int FindFirstBitls1(int num) {
    int indexBit = 0;
    while ((num & 1) == 0) {
        num = num >> 1;
        ++ indexBit;
    }
    return indexBit;
}
//判断数组中的元素是否指定的位为1
_Bool IsBit1(int num, int indexBit) {
    num = num >> indexBit;
    return (num & 1);
}

void number(int array[], int n, int a, int b) {
    int i,j;
    int result = 0;
    for (i = 0; i

你可能感兴趣的:(第一周)