记一个n*m算法复杂度的优化过程

需求:

一份关键字文件按行存储,数量大概在3-4万。
一份待查文件按行存储,大概在150万行左右。


要求遍历关键字文件,找到待查文件中包含该关键字的所有行,然后做聚合计算(本文不讨论聚合计算的问题)。
由于遍历查找的过程是”包含“,因此按照传统方法实现的算法复杂度是n*m.这个实现方法明显是不可接受的。
必须要想出优化方案。


优化方案:

方案一:

由于本人之前对mysql研究比较多,于是想到了myisam引擎的全文索引。


具体实现方案是:
1、将待查文件load data到myisam引擎的表里面。
2、对相应的列创建全文索引。
3、遍历关键字文件,调用mysql查询接口查询全文索引表。


方案分析:
经过实践这个方案主要时间消耗在创建索引上,因为mysql的全文索引是比较耗时的,查询耗时也不少,平均在1.5秒左右。
不过比起最原始的方案,已经有了比较明显的优化,但还是不能满足最终性能的要求。


方案二:

想到了之前研究lucene的时候倒排序索引的原理,是可以借鉴过来的。


具体实现方案是:
1、对待查文件每行进行分词。
2、将切好的词与待查文件的每行建立映射关系,key:关键字,value:待查文件的行的list.
3、查询时之间map.get(key)就行。


主要讲讲分词。
对于分词当然就需要词库,这里很简单,关键字文件就是词库。也就是说拿关键字作为词库对待查文件的每行进行分词,然后建立二者之间的mapping关系。
其实这就是一个倒排序的过程,算法复杂度由n*m降低到了n的复杂度。


对于分词工具得选择,我采用了mmseg4j,但mmseg4j有个弊端,如果词库中有中文+ask码字符的词时,它是不能按要求切分的。
于是看了下mmseg4j的源码,简单的修改了下源码,实现了我的要求。




第一次写博客,如果有不准确的地方请大家多多指导。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值