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;
    }
  • 相关阅读:
    20150216 IMX257实现GPIO-查询按键驱动程序
    20150216简单的Linux字符设备驱动程序
    Linux内核驱动编程
    解决安装完centos6.6之后/etc/sysconfig/目录下没有iptables 的问题
    centos6.6安装配置jboss7.1.1
    mysql5.6中 order by 多个字段排序问题
    centos6.6编译安装lnmp系列之PHP
    centos6.6编译安装lnmp系列之nginx
    centos6.6编译安装lnmp系列之mysql
    mysq 安装时候进行生成数据库系统时候执行语句 ./scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql 时候报错
  • 原文地址:https://www.cnblogs.com/wangbogong/p/3129511.html
Copyright © 2011-2022 走看看