有关数组中出现不成对数字的例题解析

来源:互联网 发布:linux系统常用命令大全 编辑:程序博客网 时间:2024/06/02 11:42

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

  思路:可以将所有数字进行异或,因为相同数字异或之后结果为0,任何数与0异或得该数字本身。此题中将所有数字进行异或的结果就是需要找的那个数字。
具体实现如下:

#include <stdio.h>#include <windows.h>int main(){    int arr[] = { 0, 1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1, 0 };    int num = arr[0];    int i = 0;    for (i = 1; i < sizeof(arr) / sizeof(arr[0]);i++)    {        num ^= arr[i];      //整体异或    }    printf("different number is %d\n", num);    system("pause");    return 0;}

结果为:

结果

2.一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。
找出这两个数字,编程实现。

  思路:有了第一题的思路,很容易想到也应用异或来完成。首先同样要将所有数字进行异或,此时异或的结果是数组中两不相同数字异或的结果,接下来只要将这两个数字分离出来便可。
  由异或的性质可知所得结果中比特位是0的表示该位相等,为1的表示该位不相等,所以我们可以根据指定比特位不同将其分组,此时两不同数字肯定不在同一组,只需在第一组和第二组内进行整体异或便能将两不同数字找出。
具体实现如下:

#include <stdio.h>#include <windows.h>#include <assert.h>void Find_different(int arr[], int len){    assert(arr);    assert(len > 2);    int i = 1;    int num = arr[0];    while (i < len)    {        num ^= arr[i];     //将所有数异或        i++;    }    int flag = 1;    i = 0;    while (i < 32)    {        if (num & (flag << i))     //判断某比特位是否为1        {            flag <<= i;            break;        }        i++;    }    i = 0;    int data1 = 0;    int data2 = 0;    for (i = 0; i < len; i++)      //根据指定比特位不同将其分组    {        if (arr[i] & flag)        {            data1 ^= arr[i];      //将分好组的数据进行整体异或        }        else        {            data2 ^= arr[i];        }    }    printf("different data= %d %d\n",data1, data2);}int main(){    int arr[] = { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8 };    int len = sizeof(arr) / sizeof(arr[0]);    Find_different(arr, len);    system("pause");    return 0;}

结果为:

结果

原创粉丝点击