寻找水王

一、实验题目

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

二、实现方法及设计思路

      1、共有三种方法可以实现此题目

      2、第一种:遍历数组,统计出每个ID出现的次数,最后在进行比较

          第二种:先将此数组按ID号进行排序,在分别统计每个ID出现的次数,最后通过比较寻找出水王

          第三种:以上两种实现起来一是比较复杂,二是执行时间比较长。

                     新方法:根据题意可知,可以通过比较相邻的两个ID号,相同的话,记录下此ID出现的次数;不同的话,消去进行比较的这两个ID。最后可知,最后剩下的ID肯定 为水王的ID.

      3、程序设计思路:

           要想通过方法三实现此程序,需这样来实现:

           设置一个整形变量NUM,此变量用来记录当前ID出现的次数,若比较相同,则变量NUM+1;若比较不同,则变量NUM-1。

           在每次循环时,读取数组中的一个数据(即ID号),对当前变量NUM进行测试,若为零,则将当前读取的ID号赋值给水王变量waterKing,否则比较waterKing和当前读入的ID号是否相同,并进行相关操作。

      4、需要注意的问题:

          (1)注意文件打开时进行判断,看文件是否打开

          (2)文件打开后,要判断文件是否为空文件。

三、实验代码

//date:2016.5.16
//content:找水王
#include<iostream>
#include<fstream>
#include<string>
using namespace std;

//函数,从文件中读入数组。此数组抽象表示帖子的列表
void getArray(string a[])
{
    string strTemp;
    fstream fstrInfile;
    fstrInfile.open("array.txt", ios::in);

    if (!fstrInfile.is_open())
    {
        cout << "文件未被打开!!" << endl;
        exit(1);
    }
    fstrInfile >> strTemp;                     //此句读入文件中第一个字符,必须和下面的判断连用
    if (fstrInfile.eof())                      //判断打开的文件是否为空,注意判断条件
    {
        cout << "打开的文件为空!!" << endl;
        exit(0);
    }

    a[0] = strTemp;
    cout << a[0] <<" ";
    for (int i = 1; i < 10; i++)
    {
        fstrInfile >> a[i];
        cout << a[i] << " ";
    }
    cout << endl;
    fstrInfile.close();
}

//函数,实现功能-找到水王。
string getWaterKing(string a[],int n)   //(数组,个数,ID)
{
    string id;            //记录水王的ID
    int intTimes=0;    //记录每个ID出现的次数
    for (int i = 0; i < n; i++)
    {
        if (intTimes == 0)
        {
            id = a[i];
            intTimes = 1;
        }
        else
        {
            if (id == a[i])
            {
                intTimes = intTimes + 1;
            }
            else
            {
                intTimes = intTimes - 1;
            }
        }
    }

    return id;
}

//主函数
int main()
{
    string strIn[10];
    string strKingID;
    /*
    string strOut[10];
    fstream fstrOutfile;
    fstrOutfile.open("array.txt", ios::out);
    if (!fstrOutfile.is_open())
    {
        cout << "文件未被打开!!" << endl;
        exit(1);
    }
    cout << "请输入10个数:" << endl;
    for (int i = 0; i < 10; i++)
    {
        cin >> strOut[i];
        fstrOutfile << strOut[i] << " ";
    }
    fstrOutfile.close();
    */

    
    getArray(strIn);
    strKingID=getWaterKing(strIn, 10);
    cout << "分析表可知水王是:" << strKingID;
    cout << endl;

    return 0;
}
 

四、实验结果截图

五、总结分析

     本次实验的实验设计思路很重要。对问题分析时,因为水王的ID出现的次数超过一半,所以在对每次相邻两个ID进行比较时,若不等则消除这两个ID,这样进行下去,可知最后一定会剩下水王的ID。

     出现的错误:对本实验进行样例测试时,ID数组使用的是整型数组,整形变量waterKing初始化0。对实验进行修改,使ID数组为字符串型数组,字符串变量waterKing初始化为NULL,此时执行此程序会报错,字符串行的变量不能初始化为空。

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