找出多个文本中频率高的单词(1)

这两天写了一个app,就是统计一堆文本文件里中,出现频率最高的一些单词。

eg,找出某个文件夹下的所有文件中出现频率最高的100个单词


整体思路:肯定是用多线程去读取,要是一个线程的话会很慢的。

1 多个线程同时去读,将读到的单词保存到自己的线程中

2 多个线程将单词汇总到主线程

3 主线程合并每个线程读到的单词

4 主线程找出频率最高的100个


ps:题外话; 并不是使用的线程越多就越快,这里面有很多原因的,简单的说几个原因

(1)有IT经验的都知道,一个cpu在某一个时刻只能跑一个线程,所以对于现在的电脑或者服务器至少是双核的,最多的话同时跑两个线程,当然如果真的跑两个线程的话不是不可以,但是依据我的经验以及一些服务器的源码,都是跑电脑的cpu数目+1个线程,例如双核就跑3个,四核跑5个(本人理解较浅,欢迎拍砖)

(2)创建线程也是需要开销的,所以线程创建多了,开销自然而然的就打了,所以java的concurrent包里有cachepool以及fixpool等线程池,但是还是有开销的。

(3)自己写个程序,然后改变线程数目,跑跑看……


具体设计:

对于步骤1: 采用java concurrent包里的线程池来创建线程,打算跑3个线程,每个线程里有个map,存储单词,以及其出现的次数

对于步骤2: 使用concurrent包里的CountDownLatch类来 通知主线程去获取子线程的map

对于步骤3:就是将子线程的每个Map合并到主线程里的一个大map中,若有相同的单词,则合并,相加其出现的频率次数

对于步骤4:找出频率最高的前多少个,我打算使用最小堆来实现,比如前100个,就一直构建大小为100的最小堆


或者不用CountDownLatch,采用concurrent 中的Future + ExecutorService


其他设计:

1 每个子线程共同使用一个map,这样就不用主线程合并了。(想法很好,但是存在一个线程安全的问题,对于hashmap它是不安全的,虽说cuConcurrentHashMap<K,V>,但是他的效率实不是很高,因为有一个线程使用它,其他的线程就必须等待!这样不如每个线程里有有一个自己的Map,最终会总到主线程就ok了)

2 使用必须使用一个最小堆找出前100个,这个纯属于我得个人想法,因为比较单词不会很多,你用一个排序算法,可以使用java里collections.sort  这个方法,他的复杂度是nlogn级别的,也是很快的,我只所以使用堆是因为 堆占用的内存比较小,只是存储100个节点


还上不上代码?有点纠结……因为代码没了还要从新写一份……


简单写写吧……下篇见!



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值