• 关键字(标签)提示组件——拼音、汉字混合搜索


       最近研究汉字转拼音,想到了拼音模糊搜索,每个网站都有关键字提示系统,自己粗略的写了一个,速度还不错,但一看内存,吓了一大跳,200多个关键字4G多内存,于是研究了一下关键字提示的算法,也就有了本文。

       由于这个算法的细节过多,只放片段代码有可能误导读者,所以本篇文章不放代码,有兴趣的同学可以下载源码研究一下。

     一、目前各大网站的关键字提示系统测试:

    关键字:程序员

    检验标准:在搜索栏输入“程序员”相关字符或拼音,弹出的关键字是否包含“程序员”,包含为判断为成功,否则为失败

    百度:程xy (成功) 程xuy(成功)程xuyuan(成功)程xyuan(失败)cxy(成功)chengxy(成功)cxuy (成功)chengy(成功)cy(成功)cyuan(失败)cx员(成功)

    淘宝:程xy (失败) 程xuy(成功)程xuyuan(成功)程xyuan(失败)cxy(失败)chengxy(失败)cxuy (失败) chengy(失败)cy(失败)cyuan(失败)cx员(失败)

    知乎:程xy (失败) 程xuy(失败)程xuyuan(成功)程xyuan(成功)cxy(失败)chengxy(成功)cxuy (失败) chengy(失败)cy(失败)cyuan(失败)cx员(失败)

    搜狗:程xy (失败) 程xuy(成功)程xuyuan(成功)程xyuan(失败)cxy(失败)chengxy(失败)cxuy (失败) chengy(成功)cy(失败)cyuan(失败)cx员(成功)

    360搜索:程xy (成功) 程xuy(成功)程xuyuan(成功)程xyuan(失败)cxy(失败)chengxy(失败)cxuy (失败) chengy(成功)cy(成功)cyuan(失败)cx员(成功)

    统计:百度9,淘宝2,知乎3,搜狗4360搜索6

    关键字提示能力:百度>360搜索>搜狗>知乎>淘宝

    个人评价:百度的提示方案是最好的,也符合一些容易忘字的用户输入观。(什么?你说输入法能解决,嗯,这是一个方法,但是,对于专业词汇,一些懒汉和电脑小白,他们才不会去下特定的词库)

    二、当前绝大数网站使用的技术:

        网上有关关键字提示的技术方案主要有以下两种:

         1、使用sql语名的like

         2、使用搜索引擎:lucenesolrelasticsearch等。

    简略评论一下:

        第一种是最简单的,数据表一列放关键字,另一列存放关键字所对应的拼音首字母,这种方案只支持纯汉字或拼音首字母的搜索,不支持汉字+拼音,也不支持全拼。这种方案最简单,问题也最多。在手机端搜索时,谁会删除前面打好的字,转成拼音首字母。

        第二种是有效的方法,要加机器,加机器就意味着要拿钱,更重要的是增加学习成本,动手写什么类。

    三、我的关键字提示系统算法原理:

        我的目标是写出一个能支持汉字、拼音、拼音首字母混合的提示系统,速度要快,内存消耗不要太大。

    方案如下:

        1、速度要快,第一个就想到tried tree

        2、如果tried tree的节点都设置返回值,内存消耗严重。所以每个节点设置返回值所在的区间。

        3、节点返回的是区间,这需要关键字排列。

        4、提示系统要支持汉字、拼音、拼音首字母混合,就要将每个节点划分成三个节点:拼音首字母、拼音、汉字。

        5、关键字排列方式为:首字母+拼音+汉字+下一个汉字排列。

        6、匹配方式跟 tried tree一样,注意的是:在匹配拼音、拼音首字母时,将子节点全部记录,用于下一次匹配。

       上面方案,对应的类是PinYinSearch,详见开源项目。

    四、关键字提示系统算法改进:

        PinYinSearch对于10W以下的关键字来说,绰绰有余。然而现实中,关键字大于10W的情况很多,如:关键字111.9W个,总字数达到512.6W字时,我们会发现这程序占内存太多了,2799M多。所以我们要改成这代码。

        于是我们开始查找相关方案:

        1、网上搜索代替tried tree的解决方案,找到“双数组trie树”。

        2、研究代码我们会发现几点:1、汉字首拼音最多26个,用byte类型足够了,2、拼音最多500个,用ushort足够了。

        3、当我们将汉字、拼音转成ushort类型时,我们会发现一个好处,当输入汉字进来匹配时,我们必须将汉字转成ushort,当汉字不存在,就没有相就的ushort,我们就可以直接返回空集合。

       上面方案,对应的类是PinYinSearchEx,详见开源项目。

    五、关键字提示系统算法测试:

        测试环境:win10  cpui5-5200U  内存:12G  DEBUG环境下

        关键字:总共111.9W个,总字数达到512.6WW

        测试关键字:程xy、程xuy、程xuyuan、程xyuancxychengxycxuychengycycyuancx员。

        运行内存:186M

        输出大小:122M

        运行速度:4秒钟运行1000次。

    六、开源项目:

        项目名称:ToolGood.Words

         GitHubhttps://github.com/toolgood/ToolGood.Words

        码云:http://git.oschina.net/toolgood/ToolGood.Words

        测试代码:【ToolGood.Words.Test->PinYinSearch->PinYinSearchExTest.cs

    注:

    感觉运行速度才有改善的地方,就不发到首页了。

  • 相关阅读:
    Flume线上日志采集【模板】
    【转】什么叫众筹?什么叫大数据?什么叫互联网思维?简单粗暴秒懂!
    【转】搞清楚LzoCodec和LzopCodec
    linux tail -f 和 tail -F的区别 && tail 的断点续传
    hadoop输出lzo文件并添加索引
    中文转Punycode
    Storm学习笔记——简介
    HBase学习笔记——Java API操作
    HBase学习笔记——配置及Shell操作
    HBase学习笔记——概念及原理
  • 原文地址:https://www.cnblogs.com/toolgood/p/6375932.html
Copyright © 2020-2023  润新知