C实现在线人数统计,请教

ccdd14 2010-01-11 09:43:37
有一份数据,包含用户ID,上线时刻(精确到秒),下线时刻(精确到秒),求某一时刻的在线人数和最高在线人数的时刻。
数据有10万条记录,不考虑用数据库存储,也不考虑内存的限制。求用C如何解决,有什么好的算法?

刚开始想的是这样,判断所求的时刻是否在上线时刻和下线时刻之间,得循环10万次进行统计。
最重要的是每次求在线人数都得循环10万次,效率太低。

请大家一起讨论。
...全文
528 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
james_hw 2010-01-13
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 xianyuxiaoqiang 的回复:]
服务器维护一个计数器,每次有人上线就++,有人下线就--,实时统计。这样效率岂不更高?
[/Quote]

才知道我打字都花了10分钟。。。
james_hw 2010-01-13
  • 打赏
  • 举报
回复
[Quote=引用楼主 ccdd14 的回复:]
有一份数据,包含用户ID,上线时刻(精确到秒),下线时刻(精确到秒),求某一时刻的在线人数和最高在线人数的时刻。
数据有10万条记录,不考虑用数据库存储,也不考虑内存的限制。求用C如何解决,有什么好的算法?

刚开始想的是这样,判断所求的时刻是否在上线时刻和下线时刻之间,得循环10万次进行统计。
最重要的是每次求在线人数都得循环10万次,效率太低。

请大家一起讨论。
[/Quote]

你看这样行不行,一个long型数组,数组长度为3600*24(动态申请,内存还是够用的),数组用来记录一天中每秒钟在线人数。

遍历记录,每条记录的有起始和结束时间,将对应时间段的元素+1,例如:在线时间从1秒到100秒,则a[1]到a[100]之间的元素全部+1,这样遍历一遍的时间是O(N*3600*24),这样数组里保存了每秒在线人数,要查询每个时刻的在线人数很easy,数组下标直接访问即可,最高在线人数,遍历一下数组,得到最大数即可。

xianyuxiaoqiang 2010-01-13
  • 打赏
  • 举报
回复
服务器维护一个计数器,每次有人上线就++,有人下线就--,实时统计。这样效率岂不更高?
ccdd14 2010-01-12
  • 打赏
  • 举报
回复
有没有第一次查找统计需要花多一些时间
以后每次统计可以明显少花一些时间
ccdd14 2010-01-11
  • 打赏
  • 举报
回复
还没弄明白
ccdd14 2010-01-11
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 hairetz 的回复:]
由于海量计时器一般是用堆来做。(这里需要对应到每个人,还需要一个hash表)

把上线的时间都维护在一个小顶堆里。
只要在堆里的都是上线的。(这个好维护,每次添加和删除数据的时候,把count加或者减,则效率由天价和删除决定)

添加就不用说了,一次sift搞定,删除,就是查找目标上线时间,效率也是一次sift,约为O(logn);

至于怎么判断谁对应哪个上线时间,把它存在hash表里即可,(既然不考虑空间,那hash时间效率约为O(1),可能冲突)。

[/Quote]
把上线的时间都维护在一个小顶堆里。只要在堆里的都是上线的。
count是统计的人数?
删除,就是查找目标上线时间?
「已注销」 2010-01-11
  • 打赏
  • 举报
回复
学习
ccdd14 2010-01-11
  • 打赏
  • 举报
回复
排序是个不错的思想
不过应该还有改进的地方
  • 打赏
  • 举报
回复
由于海量计时器一般是用堆来做。(这里需要对应到每个人,还需要一个hash表)

把上线的时间都维护在一个小顶堆里。
只要在堆里的都是上线的。(这个好维护,每次添加和删除数据的时候,把count加或者减,则效率由天价和删除决定)

添加就不用说了,一次sift搞定,删除,就是查找目标上线时间,效率也是一次sift,约为O(logn);

至于怎么判断谁对应哪个上线时间,把它存在hash表里即可,(既然不考虑空间,那hash时间效率约为O(1),可能冲突)。
cattycat 2010-01-11
  • 打赏
  • 举报
回复
海量计时器可以说说吗,头一次听到。
ccdd14 2010-01-11
  • 打赏
  • 举报
回复
说说看
cattycat 2010-01-11
  • 打赏
  • 举报
回复
按我说的那样,排序是关键,最后只需顺序遍历就行了。
  • 打赏
  • 举报
回复
呵呵,这个问题我被问过。。

怎么说呢,这类题可以用一种海量计时器来实现。
Wind_Runner 2010-01-11
  • 打赏
  • 举报
回复
求某时刻在线人数,是不是可以这样:
把10万条记录分成若干个例如10个区间,则第一次需要全遍历和对上线时间排序,
以后就不用全遍历了,要得到某个区间,直接到相应区间去找,每次只需要找1万条记录。
cattycat 2010-01-11
  • 打赏
  • 举报
回复
需要按下线时刻排序吧,这样,某一时刻的在线人数只要找到这个下线时刻,顺序统计一部分数据就能算出来。
最高上线人数时刻需要对所有时刻在线人数进行统计,找出最大的,感觉这样好像性能不太好。
ccdd14 2010-01-11
  • 打赏
  • 举报
回复
哦哦
z569362161 2010-01-11
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 ccdd14 的回复:]
然后怎么做,请说出完整的思路。
[/Quote]

还问什么?他只会说不会做
ccdd14 2010-01-11
  • 打赏
  • 举报
回复
然后怎么做,请说出完整的思路。
lihan6415151528 2010-01-11
  • 打赏
  • 举报
回复
读取配置文件
z569362161 2010-01-11
  • 打赏
  • 举报
回复
很有难度。想一想
加载更多回复(8)
内容概要:本文档为程序设计基础上机测试题集1,涵盖多个编程练习题目,包括但不限于:发奖金(优化纸币组合)、求闰年数(计算指定年份内的闰年总数)、猴子吃桃(使用倒推法解决递减问题)、小游戏(判断数字之和是否为特定数值的倍数)、考拉兹猜想(验证数学猜想并打印序列)、凯撒密码(实现简单的字符加密算法)、百钱买百鸡(解决古代数学问题)、素数判定(判断输入是否为素数)、计算平均成绩统计不及格人数(处理学生成绩数据)以及打印数字图案(根据输入生成特定格式的数字矩阵)。每个题目都提供了具体的输入输出示例和C/C++代码实现。 适合人群:计算机专业学生或具有一定编程基础的学习者,尤其是正在学习C/C++语言和基础算法的人群。 使用场景及目标:①作为课堂作业或课后练习,巩固所学知识;②用于编程入门考试或竞赛准备;③帮助初学者理解常见算法思想和编程技巧,提高解决问题的能力。 阅读建议:建议读者先尝试独立完成每个题目,之后再参考提供的代码实现,对比自己的思路与标准答案之间的差异,注意代码规范性和效率优化。对于不太理解的地方,可以通过查阅相关资料或向老师请教来加深理解。

70,037

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧