• 一组数组中只有一个数(两个数)出现一次,其他的都成对出现,找出该数


    一组数据中只有一个数字出现了一次。其他所有数字都是成对出现的。请找出这个数字。(使用位运算)
         >可以这么理解:如果两个数相等,它们异或之后的结果是0。而0与任何数异或都是该数本身。
       (比如00000001^00000001结果是0。00000000^00000001=00000001)  
        那么将一组数中所有元素异或,相同的数字结果是0,最后的结果就是单独出现的数字。 
    编程实现如下:
    #include <stdio.h>
    #include <windows.h>
    int main()
    {
        int arr[]={1,2,3,4,5,1,2,3,4};
        int i=0;
        int j=0;
        for(i=1;i<sizeof(arr)/sizeof(arr[0]);i++)
        {
        arr[0]=arr[0]^arr[i];  //将它们整体异或
    }
    printf("the single is:%d
    ",arr[0]);
    system("pause");
    return 0;
     }

    那如果是一组数据中有两个数字出现了一次。其他所有数字都是成对出现的。该如何找出这两个数字。(使用位运算)

         这个问题用常规的方法也可以做,依次遍历数组,查找不相同的数,打印出来。
    但接着用上面的方法该怎么做呢,首先我们先分析一下:和上面的一样将整个数组异或一遍,得到一个结果,该值可以看成是要查找的两个数异或得来的。
    比如一组数1,2,3,1
      1:     00000001
      1:     00000001
      2:     00000010
      3:     00000011
      异或:00000001
    整体 异或值肯定不等于1,那么找比特位不为0的位,该位处相同的数据,比特位是一样的;该位处不同的数据比特位是不一样的,现在分两个组分别存放这两部分,即相同的数据划分到一组,不同的数据划分到不同组。不用考虑每组中存放多少个元素,反正相同的数据肯定放在一个组中。然后问题就转化为第一题的样式,即每个分组中有一个数出现了一次,其他数都是成对出现。
    代码实现如下:
    #include <stdio.h>
    #include <windows.h>
    #include <assert.h>
    void find_diff_data(int arr[],int len)
    {
        assert(arr);
        assert(len>2);
        int i = 0;
        int value = arr[0];
        for(i = 0;i < len;i++)
        {
            value ^= arr[i];  //整体异或
        }
        int farg = 1;
        i = 0;
        while(i < 32)
        {
            if(value & (farg <<= i))  // 查找为1的比特位
            {
                break;
            }
        i++;
        }
        i = 0;
        int data1 = 0;
        int data2 = 0;
        for(i = 0;i < len;i++)
        {
            if(arr[i] & farg)
            {
                data1 ^= arr[i];  
            }
            else
            {
                data2 ^= arr[i];
            }
        }
        printf("%d  %d",data1,data2);
    }
    int main()
    {
        int arr[] = {1,2,3,4,5,6,1,2,3,4};
        int len = sizeof(arr)/sizeof(arr[0]);
        find_diff_data(arr,len);
        system("pause");
        return 0;
    }
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    String类的intern()方法,随常量池发生的变化
    JDK8的JVM内存结构,元空间替代永久代成为方法区及常量池的变化
    wait()、notify()方法原理,以及使用注意事项--丢失唤醒、虚假唤醒
    消费者、生产者Java代码示例,wait-notify实现
    volatile、Synchronized实现变量可见性的原理,volatile使用注意事项
    CAS及其ABA问题
    JUC包Lock机制的支持--AQS
    JUC包实现的同步机制,原理以及简单用法总结
    Synchronized机制下偏向锁、轻量级锁、重量级锁的适用场景
    临时表循环插入
  • 原文地址:https://www.cnblogs.com/xjq6898/p/7819745.html
Copyright © 2020-2023  润新知