软件工程课堂作业(十四)——揪出“水王”

寻找论坛的传说‘水王’:高效算法与程序实现
本文介绍了一种快速找出灌水论坛中发帖数量超过总数一半的‘水王’的算法及其实现过程。通过避免排序操作,采用两两连续比较的方法,仅遍历一次即可找到所需ID。程序示例展示了具体实现步骤,并讨论了优化时间复杂度的策略。

一、题目:

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

      如果你有一张当前论坛的帖子(包括回帖)列表,其中帖子的作者ID在其中,请设计算法快速找到这个传说中的“水王”。

二、设计思路:

      1、首先要快速找到,要求时间复杂度要低。如果进行ID数目多少排序的话,时间复杂度至少为O(n*lgn),所以不能排序;

      2、要想遍历一遍就能找到最多出现的ID,可以将数目少的ID删掉或屏蔽,那么剩下的就是要找的。因为题目中给出条件“该ID出现次数超过总和的一半”,所以,可两两连续比较,若不一样,则第一个ID置0,向后进行;若一样,则该数的计数器加1,最后输出计数器最大的ID。

三、源代码:

 1 //找“水王”——胡亚宝——2015/04/21
 2 
 3 #include "stdafx.h"
 4 
 5 int _tmain(int argc, _TCHAR* argv[])
 6 {
 7     int a[100],count[50];
 8     int len,max=0,flag;
 9     printf("请输入元素个数:");
10     scanf("%d",&len);
11     printf("请输入各元素:");
12     for(int i=0;i<len;i++)
13     {
14         scanf("%d",&a[i]);
15         count[a[i]]=0;
16     }
17 
18     for(int j=0;j<len-1;j++)
19     {
20         if(a[j]==a[j+1])
21         {
22             count[a[j]]++;
23             if(count[a[j]]>max)
24             {
25                 max=count[a[j]];
26                 flag=j;
27             }
28         }
29 
30         if(a[j]!=a[j+1])
31         {
32             a[j]=0;
33         }
34     }
35 
36     printf("出现次数最多的元素为:%d\n",a[flag]);
37     return 0;
38 }

四、运行结果:

五、心得体会:

      首先我想出的解题思路是先排序,再查找,这样根据出现次数的多少排序以后,很容易就能找出“水王”。但此时时间复杂度不符合要求,还需要改进。

      如果时间复杂度为O(n),那么不能排序,一旦排序再去查找就要嵌套,所以要想出一个将所有的数遍历一遍就能找出的方法。此时有一个前提条件,就是该数出现的次数超过总次数,这样它和每一个数配对,最后总会剩下该数。所以可从第一个数开始,每一个数和它后面的数进行比较,若两数不相同,则可去除第一个数,第二个数接着与它后面的进行比较;若两数相同,那么该数的计数器加1。比到最后,一定是出现次数最多的数的计数器最大,那么此时输出该数。这样,只遍历一遍,就能找出该数。

      这次的算法也是主要考察时间的优化,开始我只想到了消除,可是消除的条件还不是很明朗,通过老师的提醒,自己下课编写了算法和程序。对于这种优化算法的问题,还是应该多多练习。

转载于:https://www.cnblogs.com/huyabaoboke/p/4445310.html

### 关于水王争霸编程竞赛 #### 水王争霸 C语言 编程竞赛概述 水王争霸是一项面向广大程序员和爱好者的编程挑战赛,旨在通过解决实际问题来提升参赛者的技术平。比赛通常会提供一系列具有不同难度级别的题目供选手解答。 对于C语言编程竞赛而言,参与者需运用标准C/C++库编写程序解决问题[^1]。上述给出的代码片段展示了如何处理交通信号灯的时间逻辑,在比赛中类似的算法设计能力是非常重要的。 #### 规则说明 - **环境准备**:确拥有支持C/C++编译器的工作站或在线平台。 - **提交形式**:按照官方指定的方式上传源码文件,注意遵循命名约定。 - **测试案例**:除了自行构建的据集外,还需考虑边界条件以及异常情况下的表现。 - **评分机制**:依据运行效率、内存占用等因素综合评定成绩;部分赛事可能还会考察代码可读性和文档质量。 #### 参与方式指导 为了参加此类活动,建议关注各大高校社团公告栏或是知名技术社区发布的消息通知。许时候这类竞赛是由特定机构主办并开放报名链接给公众注册加入。另外也可以留意社交媒体上的宣传帖文获取最新动态。 ```c++ // 示例:简单的输入输出练习题 #include <iostream> using namespace std; int main(){ int num; cout << "请输入一个整:" ; cin >> num; cout << "您输入的是:" << num << endl; return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值