zoukankan      html  css  js  c++  java
  • 寻找发帖水王

      在<<编程之美>>这本书中提到了发帖水王的问题。

      原始问题:Tango是微软亚洲研究院的一个试验项目。研究院的员工和实习生们都很喜欢在Tango上面交流灌水。传说,Tango有一大“水王”,他不但喜欢发贴,还会回复其他ID发的每个帖子。坊间风闻该“水王”发帖数目超过了帖子总数的一半。如果你有一个当前论坛上所有帖子(包括回帖)的列表,其中帖子作者的ID也在表中,你能快速找出这个传说中的Tango水王吗? 

      扩展版本:随着Tango的发展,管理员发现,“超级水王”没有了。统计结果表明,有3个发帖很多的ID,他们的发帖数目都超过了帖子总数目N的1/4。你能从发帖ID列表中快速找出他们的ID吗?

      先看原始问题,假设ID序列是已经排序好的,序列的长度为N,那么第2/N个元素一定是我们需要找的那个元素,算法时间复杂度O(1)。然而,若是未排序的,那么算法排序的时间复杂度O(N*logN)。很显然,对于这个问题,如果只用用排序方法解决,那就没有多大的存在价值,因此,需要进一步的思考当前问题。实际上,如果我们在序列中删除两个不同的元素,我们需要寻找的“水王”,仍然存在于余下的序列当中,但问题的规模已经被我们简化(适合算法设计思想中的分治与递归)。

    #include <iostream>
    
    using namespace std;
    
    typedef int Find_Type;
    
    Find_Type find_type(int* array, int N)
    {
        Find_Type candinate;
        int nTimes=0;
        for (int i=0; i != N; i++)
        {
            if ( 0 == nTimes)
            {
                candinate = array[i];
                nTimes++;
            }
            else
            {
                if (array[i] == candinate)
                {
                    nTimes++;
                }
                else
                {
                    nTimes--;
                }
    
            }
        
        }
        return candinate;
    }
    int main()
    {
        int array[] = {1,2,2,2,3,4,2,2,5};
        Find_Type candinate = find_type(array, sizeof(array)/ sizeof(int));
        cout<<candinate;
        system("pause");
        return 0;
    }

       拓展版本类似与原问题,将三个ID看出一个整体,解决思路与第一个相似,不同的是的需要保存三个nTimes。在遍历过程中,当前ID不同与保存的三个ID,若某个ID的nTimes等于0,则用当前ID替换掉该ID,若不存在,则将三个ID的nTimes均减1。

    #include <iostream>
    
    using namespace std;
    
    typedef int Find_Type;
    
    Find_Type* find_3type(int* array, int N)
    {
        const int cand_num = 3;
        Find_Type *cand_list = new Find_Type[cand_num];
        int nTimes[cand_num] = {0};
        for (int i = 0; i != cand_num; i++)
        {
            cand_list[i] = -1;
        }
    
        for (int i = 0; i != N; i++)
        {
            int currentID = array[i];
            int tag = -1;
    
            for (int i = 0; i != cand_num; i++)   //判断当前的ID与保存的三个ID某个ID相同, -1表示不存在
            {
                if (currentID == cand_list[i])
                {
                    tag = i;
                    break;
                }
            }
    
            if (-1 == tag)               //当前ID与保存的三个ID均不同
            {
                int j=0;
                for (; j != cand_num; j++)
                {
                    if (0 == nTimes[j])  //如果三个ID中,某个ID的nTime等于0,则将当前ID赋值给该ID,其nTime赋值1
                    {
                        cand_list[j] = currentID;
                        nTimes[j] = 1;
                        break;
                    }
                }
                if (j == cand_num)       //如果三个ID均不存在nTime等于0的,则将三个ID的nTime减1
                {
                    for (int k = 0; k != cand_num; k++)
                    {
                        nTimes[k]--;
                    }
                }
            }
            else                         //当前ID与保存的某个ID相同,则该ID的nTimes加1
            {
                nTimes[tag]++;
            }
        }
        return cand_list;
    }
    
    int main()
    {
        int array[] = {1,2,2,3,4,2,2,3,3,4,4};
        int cand_num =3;
        Find_Type* cand_list = find_3type(array,sizeof(array) / sizeof(int));
        for (int i = 0; i != cand_num; i++)
            cout<<cand_list[i]<<"\t";
        system("pause");
        return 0;
    }
  • 相关阅读:
    STL:set/multiset用法详解
    STL:list用法详解
    STL:deque用法详解
    STL:vector容器用法详解
    Axure RP chrome插件显示已损坏或者无法安装的解决方法
    怎样知道自己机器的出口网关IP(即外部IP)
    [Selenium]怎样验证页面是否有无变化
    [Selenium]刷新页面 Refresh page
    [SoapUI]怎样获取隐藏元素的文本内容Get text of hidden element
    [SoapUI]怎样从应答报文中获取某个字段的值,然后用其改写某个变量
  • 原文地址:https://www.cnblogs.com/wangbogong/p/3129511.html
Copyright © 2011-2022 走看看