课堂练习-找水王
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了课堂练习-找水王相关的知识,希望对你有一定的参考价值。
问题描述:
•三人行设计了一个灌水论坛。信息学院的学生都喜欢在上面交流灌水,传说在论坛上有一个“水王”,他不但喜欢发帖,还会回复其他ID发的每个帖子。坊间风闻该“水王”发帖数目超过了帖子数目的一半。
•如果你有一张当前论坛的帖子(包括回帖)列表,其中帖子的作者的ID也在其中,你能快速的找到这个传说中的水王吗?
问题分析:
分析问题发现,帖子列表好比一个一维数组arry,arry[0]的内容就是第0贴子的发帖人,问题就可以抽象成:一个长度为N一维数组中有大于等于[N/2]+1个元素相同(一半以上元素相同),找出相同的元素。
设计思想:
可以采用两两消除法,具体实现就是对数组中不同的两个元素进行消除,最终剩下来的一定就是要找的那个元素。在程序实现中需要按序(顺序或者倒序)进行操作,但原理是相同的。对数组遍历一遍,在遍历到arry[i]个元素时,count记录前arry[0]-arry[i-1]个元素两两消除后剩余未消除的个数(这剩余的count个元素肯定是相同的),ID记录着未消除元素的内容,最终ID就是所求元素。
程序代码:
//2016/5/17 #include<iostream> void main() { int i = 0; int count = 0; //用于记录数组前N个数中的元素两两不同则消除的剩余数 int ID; //用于记录ID int arry[] = { 1, 2, 3, 1, 4, 1, 1, 1, 8, 1 ,6 ,1 }; //帖子列表,下标是帖子ID,内容是发帖人ID for (; i < sizeof(arry)/sizeof(arry[0]); i++) { if (count == 0) //如果count减为0,代表前i-1个ID两两消除,更新ID和count { ID = arry[i]; count = 1; } else //否则继续与下个元素进行两两消除或者增加相同元素个数 { if (ID == arry[i]) //增加相同元素的个数 { count++; } else //消除 { count--; } } } //输出水王ID std::cout << "水王的ID是 " << ID << std::endl; }
实现截图:
arry[] = { 1, 2, 3, 1, 4, 1, 1, 1, 8, 1 ,6 ,1 };
arry[] = { 2, 5, 6, 6, 5, 5, 5 };
个人总结:
这个问题有很多解法,最简单的就是对数组中的每一个元素的出现次数进行计数,最后再找到出现次数最多的那个元素,但是这种方法是要以牺牲时间和空间作为代价的,其实如果能找出问题所潜藏的一面,加以利用方法往往可以简单很多,就比如本例。然而,这也正是困难所在。
以上是关于课堂练习-找水王的主要内容,如果未能解决你的问题,请参考以下文章