代码之家  ›  专栏  ›  技术社区  ›  Lieven Keersmaekers

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

  •  42
  • Lieven Keersmaekers  · 技术社区  · 15 年前

    当我读到这个的时候( 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. 作者从未尝试过他们的算法,除了 AACACBBCCBCC ,完全不称职,应当场解雇 (可疑的) .
    2. 我显然错过了什么 ,必须禁止stackoverflow,绝不允许再次接触任何涉及逻辑的内容。

    注意:这是一个 C++ implementation of the algorithm 来自Niek Sanders。我相信他正确地实现了这个想法,因此它也有同样的问题(或者不是吗?).

    5 回复  |  直到 8 年前
        1
  •  45
  •   rmmh CJ Cullen    11 年前

    该算法仅在集合中有大多数元素(超过一半的元素是相同的)时才起作用。 AAACCBB 在你的例子中没有这样的多数。最常见的字母出现3次,字符串长度为7。

        2
  •  27
  •   TheCrazyProgrammer    8 年前

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

    1. 运行摩尔投票算法的第一部分 只给你一个候选人 对于大多数元素。注意这里的“候选人”。

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

    第一次迭代是为了找到候选的&second迭代是为了检查这个元素在给定数组中是否经常出现。

    因此,时间复杂性是: O(n) + O(n) ≈ O(n)

        3
  •  7
  •   j_random_hacker    15 年前

    从第一个链接的SO问题开始:

    其属性是数组中超过一半的项等于n

    从Boyer和Moore页面:

    如果存在这样的元素,那么序列中的哪个元素占大多数

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

        4
  •  0
  •   feliciafay    11 年前

    我为这个算法编写了一个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;
    }
    
        5
  •  0
  •   Peter Rui    10 年前

    当测试用例为“aaaccbb”时,集合没有多数。因为“aaaccbb”的长度为7,所以没有任何元素出现超过3次。

    以下是“Boyer和Moore线性时间投票算法”的代码:

    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;
        }