zoukankan      html  css  js  c++  java
  • 课堂练习-找水王

    三人行设计了一个灌水论坛。
    信息学院的学生都喜欢在上面交流灌水,传说在论坛上有一个“水王”,他不但喜欢发帖,还会回复其他ID发的每个帖子。
    坊间风闻该“水王”发帖数目超过了帖子数目的一半。
    如果你有一张当前论坛的帖子(包括回帖)列表,其中帖子的作者的ID也在其中,你能快速的找到这个传说中的水王吗?

    程序实现的是第一种方法!!!

    第一种方法:
    基于的原理是:“水王”在这个论坛中的帖子数是最多的,只要找出最多帖子的id,即为“水王”。
    假如有10个id,依次为a b c a b d c b a c
    将第一个id即a放入b【0】,num【0】=1;然后把第二个id即b和b【0】比较,不相同,则把b放入b【1】,num【1】=1;将c和b【0】,b【1】比较,
    发现都不同,则将c放入b【2】,num【2】=1;将第四个id即a和前面的b【i】比较,发现和b【0】相同,则将num【0】++;然后依次比较后面的id值,
    若和前面有相同的,则对应的num【】++;若都不相同,则另外放入一个b【】,对应一个num【】。
    最后将所有的num【i】进行大小比较,找出最大的num【】,即为“水王”。

    对应的流程如下:

    1。输入帖子数量int型,变量为number,然后依次输入帖子的id,string id【number】类型。
    2。定义一个string b【number】数组,用来放相同种类id的名称。定义一个int num【number】数组,用来记录相同种类id出现的次数。定义一个int add=1,用于记录有几种id出现,初始化为1,是因为第一个id已经是第一种了,再出现的话就是第二种id了。
    3。将第一个id【0】放入b【0】,num【0】=1;表示id【0】出现,并且出现了1次。
    4。循环运算后面的id,依次和前面种类的id进行比较。如果有相同种类的id,则这种id的num【】++,如果比较完之后发现没有相同种类的id,则将这种id设为新种类的id即b【add】,同时num【add】,然后add++,准备作为下一种新种类的id。
    5。在比较的过程中,如果发现有哪种id的次数大于等于了总数的一半,则将这种id打印,即为“水王”,同时结束整个程序。
    6。如果一直没有哪种id满足一半的条件,则按照过程4执行。最后将num【】比较,找出最大的num【】,即为“水王”。

    第二种方法:
    基于的原理是:题目中有一句“水王”会回复其他ID发的每个帖子,则表示每个发帖的回帖中都有“水王”的id,则把每组回帖进行比较,找出相同的id即可。
    假如每个发帖id和若干回帖id是一组对应关系,即liming发帖,然后回帖id有a,b,c,d,假如把liming和abcd看作是对应的一组,
    则从第二组回帖id开始,与第一组中的回帖id进行比较,取出相同的id;然后将第三组回帖id与前面取出的相同id进行比较,再取出相同id值。
    往后依次循环,直到只取出一个相同id值,即为“水王”。

    源代码:

    #include <iostream>
    #include <string>
    #define N 100
    using namespace std;
    void main()
    {
        int number = 1; //number为帖子的数量
        cout << "请输入帖子数量:";
        cin >> number;
    
        string id[N];  //id【】为各帖子的id值
        cout << "请依次输入帖子的id:" << endl;
        for(int i = 0; i < number; i++)
            cin >> id[i];
    
        string b[N];  //b[N]用来存放相同id的名称,用于进行比较。
        int num[N] = {1}; //num[N]用来记录相同id出现的次数,第一个id第一次出现时,出现了1次
        int add = 1; //add计数变量,用于当后面id比较不相同时,新添放入b【】时,
        //进行计数.后面比较的时候,从第二个id开始比较的,所以add初值为1
    
        b[0] = id[0]; //用于后面进行比较。
        for(int i = 1; i < number; i++)
        {
            int x = 0; //用于下面两个if,当下一个id和前面所有id比较完,没有一个相同的时候,
            //则将此id新添入b【】;假如只要有一个相同的id,则不加入
            for(int j = 0; j < add; j++)
            {
                if(id[i] == b[j]) //后面的id和前面每种id比较的时候,如果相同,那么这种id就++,表示出现次数加1
                {
                    num[j]++;
                    //根据水王帖子数大于等于总数的一半,如果有哪种id的出现次数满足这个条件,则程序终止,同时也不需要全部遍历了。
                    //如果没有超过一半的,则全部遍历,按出现次数最多的id为水王
                    if(num[j]>=(int)((number+1)/2))
                    {
                        cout<<"水王是:"<<b[j]<<endl;
                        exit(1);
                    }
                    x = 1; //设置x是监视哨,只要比较过程中有一次相同的,那么就不能把当前的id设为新种类的id
                }
            }
            if(x == 0) //如果比较之后,发现都不同,那么将这个id设为新一种id,同时新种类的id出现次数自动为1
            {
                b[add] = id[i];
                num[add] = 1;
                add++;
            }
        }
        for(int k = 0; k < add; k++)
        {
            cout << "" << k + 1 << " 个id为:" << b[k] << ",出现次数为:" << num[k] << endl;
            //将得出的所有种类id出现的次数进行比较,最大的即为水王
            if(num[k + 1] > num[0])
            {
                num[0] = num[k+1];
                id[0] = b[k + 1];
            }
        }
        cout << "所以水王为:" << id[0] << endl;
    }

    总结:

    修改之后的程序好处在于,加了

    if(num[j]>=(int)((number+1)/2))
                    {
                        cout<<"水王是:"<<b[j]<<endl;
                        exit(1);
                    }

    这样一个判断,当某种id数满足一半这个条件时,程序就会终止,不需要全部遍历。
    而如果一直没有哪种id满足一半,程序会遍历全部id,找到出现次数最多的id,即为“水王”。
    但是博客一开始写的第二种方法是不需要遍历全部id的,所以第二种方法寻找水王的速度会快很多。

  • 相关阅读:
    前端性能优化成神之路--图片懒加载(lazyload image)
    前端性能优化成神之路-异步加载
    浮动布局详解
    布局:上下两个div高度固定,中间自适应
    盒子模型和弹性盒子模型的详解
    CSRF攻击详解
    使用Base64格式的图片制作ICON
    如何让父元素有透明度,但里面的子元素不透明
    父级元素以及子元素高度宽度未知如何实现水平垂直居中
    php file文件操作函数
  • 原文地址:https://www.cnblogs.com/diyunfei/p/5511821.html
Copyright © 2011-2022 走看看