摩尔投票算法

简介

引入

  一个大小为 n 的整数序列 ,若存在一个数字 x 在这个序列中出现的次数大于  ,那么称 x 为这个序列的主元素。  

理解

  摩尔投票算法是基于这个事实:

    每次从序列里选择两个不相同的数字删除掉(或称为“抵消”),最后剩下一个数字或几个相同的数字,就是出现次数大于总数一半的那个。

  或者更形象一点:

    几个国家一起打架,假设你方人数超过总人数一半以上,并且能保证每个人出去干仗都能一对一同归于尽。不论是其他国家都联合起来对付你,或者其他国家也存在相互攻击的情况,只要你方不要内斗,最后肯定都是你赢。

实现

int  Majority(int A[],int n)
{  
    int i,c,count=1;
    c=A[0];
    for(i=1;i<n;i++) 
    {  
        if (A[i]==c) 
            count++;  
        else 
        {  
            if(count>0) 
                count--;  
            else 
            {  
                c=A[i];
                count=1;  
            }  
        }  
    }  

    if (count>0) 
        for(i=count=0;i<n;i++) 
            if(A[i]==c) count++;  

    if (count>n/2)   return c;  
    else return -1;  
}

扩展

  一个大小为 n 的整数序列,最多存在(k - 1)种数字在序列中出现的次数大于  。

以 k = 3 为例

void Majority(int A[],int n)
{
        int i,n1=A[0],count1=1,n2=A[1],count2=1;
        for(i=2;i<n;i++) 
        {
            if (A[i] == n1) count1++;
            else if(A[i] ==n2) count2++;
            else if(count1==0) 
            {
                n1=A[i];
                count1=1;
            }
            else if(count2==0) 
            {
                n2=A[i];
                count2=1;
            }
            else 
            {
                count1--; 
                count2--;
            }
        }
        
        for(i=count1=count2=0;i<n;i++) 
        {
            if(A[i]==n1) 
                count1++;
            else if(A[i]==n2) 
                count2++;
        }

        if(count1>n/3) printf("%d",n1);
        if(count2>n/3) printf("%d",n2);
}
posted @ 2020-06-13 17:23  Vivid-BinGo  阅读(315)  评论(0编辑  收藏  举报