寻找水王2——寻找三个小水王

一、实验题目

       三人行设计了一个灌水论坛。信息学院的学生都喜欢在上面交流灌水,传说在论坛上有一个“水王”,他不但喜欢发帖,还会回复其他ID发的每个帖子。坊间风闻该“水王”发帖数目超过了帖子数目的一半。
       如果你有一张当前论坛的帖子(包括回帖)列表,其中帖子的作者的ID也在其中,你能快速的找到这个传说中的水王吗?(参考核心代码)
随着论坛的发展,管理员发现水王没有了,但是统计结果表明,有三个发帖很多的ID。据统计他们的发帖数量超过了1/4,你能从发帖列表中快速找到他们吗?

二、实现方法及设计思路

      思路迁移。根据上一篇博客——找水王。经过思路拓展迁移,我们可以得到这次试验的解题思路。

      首先我们要知道,当我们每次检查四条记录的情况时,若四条记录都不是同一个人,那么可以将这四条记录全部删去,那么这样不会影响最终结果,但是

如果有属于同一个人的记录,那么我们让这个人的记录的个数增加一。一直这样循环检查下去,最后我们会发现只剩下三个小水王的记录,那么这就是我们要

找的最终结果。

三、实验代码

//data:2016.5.27
#include<iostream>
#include<string>
#include<fstream>
using namespace std;

void getArray(string a[])
{
    string strTemp;              //获取文件中第一个字符,判断文件是否为空
    cout << "读取帖子列表可得:" << endl;
    fstream fileIn;
    fileIn.open("id.txt", ios::in);       //从文件id.txt中读取帖子列表
    if (!fileIn.is_open())                //判断文件是否被打开
    {
        cout << "没有打开文件!!" << endl;
        exit(0);
    }
    fileIn >> strTemp;                     //此句读入文件中第一个字符,必须和下面的判断连用
    if (fileIn.eof())                      //判断打开的文件是否为空,注意判断条件
    {
        cout << "打开的文件为空!!" << endl;
        exit(0);
    }

    a[0] = strTemp;                 //打开的文件不为空,读入文件的内容
    cout << strTemp << endl;
    for (int i = 1; i < 20; i++)
    {
        fileIn >> a[i];
        cout << a[i] << endl;
    }
    fileIn.close();
}

void getWaterRing(string strItem[])
{
    int intCount[3] = { 0, 0, 0 };        //设置三个变量,用来计数,记录ID号出现的个数
    string strID[3] = { "#", "#", "#" };  //设置三个变量,用来记录ID号

    //以下为查找三个小水王的操作
    for (int i = 0; i < 20; i++)
    {
        if (strID[0] == strItem[i])
        {
            intCount[0] = intCount[0] + 1;
        }
        else if (strID[1] == strItem[i])
        {
            intCount[1] = intCount[1] + 1;
        }
        else if (strID[2] == strItem[i])
        {
            intCount[2] = intCount[2] + 1;
        }
        else if (intCount[0] == 0)
        {
            intCount[0] = 1;
            strID[0] = strItem[i];
        }
        else if (intCount[1] == 0)
        {
            intCount[1] = 1;
            strID[1] = strItem[i];
        }
        else if (intCount[2] == 0)
        {
            intCount[2] = 1;
            strID[2] = strItem[i];
        }
        else
        {
            intCount[0] = intCount[0] - 1;
            intCount[1] = intCount[1] - 1;
            intCount[2] = intCount[2] - 1;
        }
    }

    cout << "第一个水王是:" << strID[0] << endl;
    cout << "第二个水王是:" << strID[1] << endl;
    cout << "第三个水王是:" << strID[2] << endl;
}

int main()
{
    string strItem[20];          //设置数组,用来记录每条帖子的ID号   ,此处可以不用初始化,若初始化为null则报错

    getArray(strItem);
    getWaterRing(strItem);

    return 0;
}

四、实验截图

五、实验心得

     通过本次试验,给我印象最深的就是思路的迁移。刚开始我也对比了上一次的算法,但是没有什么头绪,同时也想了其他办法,但都有些行不通,最后请教同学才将此题目完成,我发现这类题的解题思路很重要,很多题目中的解题思想值得我们去好好思考。

原文地址:https://www.cnblogs.com/seven-seven/p/5536433.html