• 查找之摩尔投票算法


      对于一个一位数组array[1,5,1,3,2,3,3,3,4,9,6,4,3,3,3,3],找出其中超过数组中一半长度的数。今天学到了一种是摩尔投票算法。其他的一种算法是首先对数组进行排序,这样从小到大,并且超过一半,该数存在的话一定在数组的正中间。这样最后对该数进行检查一遍,因为有可能对于刚好是等于一半的数。

      摩尔投票算法的思想是,首先定义一个majority和一个count,majority用来存放当前出现次数最多的数。如当majority等于第一个数后,count=1;然后majority与第二个数比较,如果相等,则count+1,否则count-1,如果减到count=0的时候,则说明该数在出现的当前序列已经不是出现次数最多的了,因此替换为当前的数。然后继续比较下去。最后同样要对得出来的数进行检验。

      

     1       public static int getValue(int[] gifts, int n) {
     3           int half=n/2; 5           int majority=0,count=0;
     6           for(int i:gifts){
     7               if(count==0){
     8                   majority=i;
     9                   count++;
    10               }
    11               else{
    12                   if(majority!=i){  //当majority与当前数i不等时,
    13                       count--;    //则计数count-1,如果count减一之后为0,则替换。
    14                   }
    15                   else{
    16                       count++;
    17                   }
    18               }
    19               if(count>half){
    20                   return majority;
    21               }
    22           }
    23           count=0;
    24           for(int i:gifts){
    25               if(majority==i){
    26                   count++;
    27               }
    29           }
    30           if(count>half){
    31               return majority;
    32           }
    33           else return 0;
    34       }    

      从找到数组中超过1/2的数变换为找到1/3的数,可以知道,数组中超过1/2的数最多一个,1/3的最多两个。

      

     1       public static String gettwomax(int[] a,int n){
     2           int m1=0,m2=0;
     3           int c1=0,c2=0;
     4           String maxTwoTimesNumber="";
     5           for(int i:a){
     6               if(m1==i){
     7                   c1++;
     8               }
     9               else if(m2==i){
    10                   c2++;
    11               }
    12               else if(c1==0){
    13                   m1=i;
    14                   c1++;
    15               }
    16               else if(c2==0){
    17                   m2=i;
    18                   c2++;
    19               }
    20               else{
    21                   c1--;
    22                   c2--;
    23               }
    24           }
    25           c1=0;
    26           c2=0;
    27           for(int i:a){
    28               if(i==m1){
    29                   c1++;
    30               }
    31               if(i==m2){
    32                   c2++;
    33               }
    34           }
    35           if(c1>n/3){
    36               maxTwoTimesNumber+=m1;
    37           }
    38           if(c2>n/3){
    39               maxTwoTimesNumber+=m2;
    40           }
    41           return maxTwoTimesNumber;
    42           
    43       }

      同样对于大于n/3的数,我们需要两个数来记录。比如数组[a,b,a,b,c],首先各自m1,m2,计数为0,当一个个条件去比较时,m1=a,c1=1,m2=b,c2=2,然后i等于a,i==m1,所以c1加一,然后i=b,c2加一,然后i=c,条件都不符合,则c1,c2都各自减一。若后续计数为0时,则把当前的数替换为m1或m2.

    jeyfang
  • 相关阅读:
    开始学习设计模式
    <转载>CCeButtonST v1.2
    CRITICAL_SECTION 学习
    简单工厂模式
    《转》Owner Draw Button StepbyStep
    低调 平和
    MFC RTTI (DECLARE_DYNAMIC 及IMPLEMENT_DYNAMIC 宏)
    为程序集延迟签名.
    NBear3.7 在 Suse11 下 的 MonoDevelop2(Alpha2)改造成功。
    Mono开发。
  • 原文地址:https://www.cnblogs.com/jeyfang/p/5347896.html
Copyright © 2020-2023  润新知