课堂小练习-找“水王”

一.题目及要求

  1)题目

    三人行设计了一个灌水论坛。信息学院的学生都喜欢在上面交流灌水,传说在论坛上有一个“水王”,他不但喜欢发帖,还会回复其他ID发的每个帖子。坊间风闻该“水王”发帖数目超过了帖子数目的一半。

  2)要求

    如果你有一张当前论坛的帖子(包括回帖)列表,其中帖子的作者的ID也在其中,你能快速的找到这个传说中的水王吗?并且,使时间复杂度为O(n)。

二.设计思路

  1)刚开始看到此要求时,首先想到的是,将它们 按照每个ID出现的次数从大到小排序,但是这样的话,时间复杂度是O(n^2)。

  2)题目的要求时,时间复杂度为O(n),遍历整个记录,利用一个计数器,每当遇到两个不同的ID时,就将它们删除。无论删除的ID中是否有水王的ID,在删除之后,水王的ID仍然超过总数的一半。

三.源代码

// 水王.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include<iostream.h>
#define max 50                    //ID数组的最大值
/*ID号的输入*/
int input(int ID[])
{
    int length;
    cout<<"请输入ID的数量:";
    cin>>length;

    for(int i=0;i<length;i++)     //ID号的输入
    {
        cin>>ID[i];
    }

    return length;                //返回值是该ID数组的长度
}
/*寻找水王*/
int searchsw(int ID[],int length)
{
    int n,i;                     //n表示为一个计数器
    int sw;
    for(i=n=0;i<length;i++)       //将ID数组遍历一遍
    {
        if(n==0)                  //给SW初始化
        {
            sw=ID[i];
            n=1;
        }
        else
        {
            if(sw==ID[i])        //若相等,则计数器加一
                n++;
            else                 //若不等,则减一
                n--;
        }
    }
    return sw;
}
int main(int argc, char* argv[])
{
    int sw;
    int ID[max];

    sw=searchsw(ID,input(ID));    //调用函数,寻找水王
    cout<<"水王是:"<<sw<<endl;

    return 0;
}

四.结果及截图

  

  

五.心得

  此题目中的关键信息是,““水王”发帖数目超过了帖子数目的一半”,掌握这个”一半“,然后逐渐的深入,程序的时间复杂度便是O(n)。

  此程序题目虽然简单,但是若将时间复杂度考虑为O(n),不容易想。在课上的时候,思路虽然想到了,但是实现还是遇到了困难,写代码是体力活,但是代码的优化就是技术活了。

原文地址:https://www.cnblogs.com/menglikanhualuo/p/4448804.html