数组中的只有1 (或2)个数字是单独出现的,其他的都是成对出现的,请找出单独出现的这1(或2)个数字

来源:互联网 发布:数据库系统概论pdf下载 编辑:程序博客网 时间:2024/06/05 23:50

这道题其实是一道进阶题,它的初级是:
一个数组中只有一个数是单独出现的,其他的都是成对出现的,请找出这个数。
大家首先想到把这个数组遍历一遍,然后进行各种操作,但是这里推荐使用一种效率更高的方法——把数组中所有元素都异或一遍,最后得到的结果就是那个单独出现的数字。
例如数组元素:1 2 4 2 1。
1^2 = 3 (0001 ^ 0010 = 0011)
3^4 = 7 (0011 ^ 0100 = 0111)
7^2 = 5 (0111 ^ 0010 = 0101)
5^1 = 4 (0101 ^ 0001 = 0100)
最后结果为4

代码实现:

int separate_figures(int *number, int size){    int i = 0;    int num = number[0];    for (i = 1; i <size; i++)    {        num ^= number[i];    }    return num;}int main(){    int arr[] = { 1, 2, 3, 4, 3, 2, 1 };    int sz = sizeof(arr) / sizeof(arr[0]);    int ret = separate_figures(arr, sz);    printf("单独出现的数字数是:%d\n", ret);    system("pause");    return 0;}

这里写图片描述

用这样的算法来做的话这道题就变的很简单了,现在来看看这道题的进阶版
数组中的只有2个数字是单独出现的,其他的都是成对出现的,请找出单独出现的这2个数字
代码如下:

#include <stdio.h>#include <windows.h>void find_single(int *number, int size){    int i = 0;    int key = number[1];    int n = 0;    int m = 0;    int flag = 1;    for (i = 1; i < size; i++)    {        key ^= number[i];   //把整个数组的元素异或,存到key里面    }    for (i = 0; i < 32; i++)  //找出key的二进制序列里面第一次出现1的位置(从右到左查找)    {        if (key & (flag<<=i))        {            break;        }    }    if (flag)    {        for (i = 0; i < size; i++)        {            if (flag & number[i])            {                n ^= number[i];            }            else            {                m ^= number[i];            }        }        printf("%d, %d\n", n, m);    }    else    {        printf("这个数组中没有单独出现的数字!\n");    }}int main(){    int arr[] = { 1, 1, 2, 2, 3, 3, 4, 5 };    int sz = sizeof(arr) / sizeof(arr[0]);    find_single(arr, sz);    system("pause");    return 0;}

这里写图片描述

阅读全文
0 0