线性时间投票算法。我不明白

时间:2009-04-23 09:22:52

标签: algorithm language-agnostic puzzle

在我阅读此内容时(Find the most common entry in an array),建议Boyer and Moore's Linear Time Voting Algorithm

如果您点击该站点的链接,则会逐步说明该算法的工作原理。对于给定的序列,AAACCBBCCCBCC它提供了正确的解决方案。

  

当我们将指针向前移动时   元素e:

     
      
  • 如果计数器为0,我们将当前候选设置为e并设置   反对1.
  •   
  • 如果计数器不为0,我们递增或递减计数器   根据e是否是当前的   候选人。
  •   
     

当我们完成时,当前   候选人是多数元素,如果   占多数。

如果我在一张以AAACCBB作为输入的纸张上使用此算法,建议的候选人将变为B 显然是错误的。

我认为,有两种可能性

  1. 作者从未尝试过除AAACCBBCCCBCC以外的任何其他算法,完全不称职,应该当场解雇(疑问)
  2. 我显然缺少某些内容,必须从Stackoverflow中被禁止,并且再也不允许触及任何涉及逻辑的内容。
  3. 注意:这是来自Niek Sanders的C++ implementation of the algorithm。我相信他正确地实现了这个想法,因此它有同样的问题(或者不是吗?)。

5 个答案:

答案 0 :(得分:45)

该算法仅在集合占多数时才有效 - 超过一半的元素相同。您的示例中的AAACCBB没有这样的多数。最常见的字母出现3次,字符串长度为7.

答案 1 :(得分:27)

小但是对其他解释的重要补充。摩尔的投票算法有两部分 -

  1. 运行摩尔投票算法的第一部分仅为多数元素提供候选。请注意这里的“候选人”一词。

  2. 在第二部分中,我们需要再次遍历数组以确定此候选项是否出现最大次数(即大于/ 2次)。

  3. 第一次迭代是找到候选人&第二次迭代是检查给定数组中该元素是否多数出现。

    所以时间复杂度是:O(n) + O(n) ≈ O(n)

答案 2 :(得分:7)

从第一个链接的SO问题:

  

具有属性,即数组中超过一半的条目等于N

来自Boyer和Moore页面:

  

如果存在这样的元素

,则序列的哪个元素占多数

这两种算法都明确假设一个元素出现至少N / 2次。 (特别注意“多数”与“最常见”不同。)

答案 3 :(得分:0)

我为这个算法编写了一个C ++代码

char find_more_than_half_shown_number(char* arr, int len){
int i=0;
std::vector<int> vec;
while(i<len){
    if(vec.empty()){     
        vec.push_back(arr[i]);
        vec.push_back(1);
    }else if(vec[0]==arr[i]){ 
        vec[1]++;
    }else if(vec[0]!=arr[i]&&vec[1]!=0){
        vec[1]--;
    }else{                   
        vec[0]=arr[i];
    }
    i++;
}
int tmp_count=0;
for(int i=0;i<len;i++){
    if(arr[i]==vec[0])
        tmp_count++;
}
if(tmp_count>=(len+1)/2)
    return vec[0];
else
    return -1;
}

,主要功能如下:

int main(int argc, const char * argv[])
{
    char arr[]={'A','A','A','C','C','B','B','C','C','C','B','C','C'};
    int len=sizeof(arr)/sizeof(char);
    char rest_num=find_more_than_half_shown_number(arr,len);
    std::cout << "rest_num="<<rest_num<<std::endl;
    return 0;
}

答案 4 :(得分:0)

当测试用例是&#34; AAACCBB&#34;时,该集合没有多数。因为&#34; AAACCBB&#34;的长度不会超过3次。是7。

以下是&#34; Boyer和Moore的线性时间投票算法&#34;的代码:

int Voting(vector<int> &num) {
        int count = 0;
        int candidate;

        for(int i = 0; i < num.size(); ++i) {
            if(count == 0) {
                candidate = num[i];
                count = 1;
            }
            else
                count = (candidate == num[i]) ? ++count : --count;
        }
        return candidate;
    }