谈谈我做拼音搜索的一点经验
谈谈我做拼音搜索的一点经验
需要注意的一些事情
本文使用的为 Java 语言解决方案。
搜索方法上,按照个人理解,有两点关键:
分词
将类似 "women" 这样的词分解成 "wo'men"。经过这样的分词,在搜索时无论通过全拼音匹配,还是首字母匹配,处理起来都比较方便。词库构建
目前我接触过的常见搜索场景有两种,它们对词库的建立有如下影响:
通讯录搜索
对词库有频繁的添加 / 删除操作。站内搜索
使用预先维护好的词库。
如果是通讯录搜索,可以在新建联系人的时候,把联系人的名字转为拼音,存入数据库中另一个记录拼音的字段,在搜索的时候通过拼音来匹配。
如果是站内搜索,可以直接建立拼音词库,搜索的时候通过拼音来匹配。
实现
首先是词库的构建。毫无疑问,我们需要为词库建一张至少包含中文词汇以及对应的拼音词汇的表。
通讯录搜索,可能会使用一些例如 pinyin4j 的第三方库,将中文字转换为拼音。当然也我们可以自己实现转换拼音的功能,如果这样做,则需要在代码中设定好中文字库和对应的拼音,同时特别注意多音字的处理。
下面是使用 pinyin4j 库的例子。使用 pinyin4j 库可以支持简体 / 繁体中文转换为拼音,而且支持带声调的格式化输出。
我们使用 Maven 来添加 pinyin4j,在 pom.xml
中添加
<dependencies><dependency><groupId>com.belerweb</groupId><artifactId>pinyin4j</artifactId><version>2.5.0</version></dependency></dependencies>
实现类:
public class Chinese {private HanyuPinyinOutputFormat format = null;private String[] pinyin;public Chinese() {format = new HanyuPinyinOutputFormat();format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);pinyin = null;}//转换单个中文字符public String getCharacterPinYin(char c) {try {pinyin = PinyinHelper.toHanyuPinyinStringArray(c, format);} catch(BadHanyuPinyinOutputFormatCombination e) {e.printStackTrace();}// 如果c不是汉字,返回nullif(null == pinyin)return null;// 多音字取第一个值return pinyin[0];}//转换一个字符串public String getStringPinYin(String str) {StringBuilder sb = new StringBuilder();for(int i = 0; i < str.length(); ++i) {String tmp = getCharacterPinYin(str.charAt(i));if(null == tmp) {// 如果str.charAt(i)不是汉字,则保持原样sb.append(str.charAt(i));} else {sb.append(tmp);//分词if ( i < str.length() - 1 && null != getCharacterPinYin(str.charAt(i + 1))) {sb.append("\'");}}}return sb.toString().trim();}public static void main(String[] args) {Chinese chinese = new Chinese();String str = "哈哈,我爱 Coding";String pinYin = chinese.getStringPinYin(str);System.out.println(pinYin);}
}
输出的结果
ha'ha,wo'ai Coding
每当有通讯录联系人更新时,采用上述方法更新数据库中的拼音字段即可。
站内搜索,词库来源可以使用搜狗标准词库和细胞词库等。
搜狗标准词库
下载的搜狗词库可以使用深蓝词库转换器来转换成 txt 文件,或者其他输入法的标准格式。
深蓝词库转换 2.0
转换为 txt 文件后,处理以后,修改成为 insert 语句,插入数据库。
最后的关键,就是将输入的拼音分词,然后与数据库中的拼音字段匹配,分词采用正则表达式实现。
分词实现:
public class PinyinUtils {//分词正则表达式public static String regEx = "[^aoeiuv]?h?[iuv]?(ai|ei|ao|ou|er|ang?|eng?|ong|a|o|e|i|u|ng|n)?";public static String split(String input) {int tag = 0;StringBuffer sb = new StringBuffer();String formatted = "";List<String> tokenResult = new ArrayList<String>();for (int i = input.length(); i > 0; i = i - tag) {Pattern pat = Pattern.compile(regEx);Matcher matcher = pat.matcher(input);boolean rs = matcher.find();sb.append(matcher.group());sb.append("\'");tag = matcher.end() - matcher.start();tokenResult.add(input.substring(0, 1));input = input.substring(tag);}if (sb.length() > 0) {formatted = sb.toString().substring(0, sb.toString().length() - 1);}return formatted;}public static void main(String[] args) {String str = "koudingboke";System.out.println(PinyinUtils.split(str));}
}
输出结果
kou'ding'bo'ke
根据此输出结果,在词库中匹配即可。
根据以上方式搜索出的词汇,会比较固定。如果有按照搜索频率对搜索结果排序的需求,可以针对每个词汇的查询计数。具体实现这里不再赘述。
个人一点粗浅经验,欢迎各位大牛一起交流。
参考来源
怎样对拼音进行切分?
Brook Zhao
本文来自 Coding 官方技术博客,如需转载请注明出处,谢谢。
谈谈我做拼音搜索的一点经验相关推荐
- 关于asterisk做呼叫转接的一点经验记录
第一天 上午接到一个需求,询问现在我们的电话系统是否能做个呼叫转接.然后在网上搜了一下,发现有路子可走,所以简单试了一下,还真是可以. 首先,需求是什么? 客户拨通了400电话到我们的asterisk ...
- 谈谈8年C++面向对象设计的经验体会
六年前,我刚热恋"面向对象"(Object-Oriented)时,一口气记住了近十个定义.六年后,我从几十万行程序中滚爬出来准备写点心得体会时,却无法解释什么是"面向对象 ...
- 命名实体识别的一点经验与技巧
最近做了一点微小的工作,搞了下命名实体识别(named entity recongnition, NER),这里总结一下目前的认识.内容比较杂,先亮一下目录,如图0-1. 图0-1 目录 一.什么是命 ...
- 命名实体识别的一点经验
最近做了一点微小的工作,搞了下命名实体识别(named entity recongnition, NER),这里总结一下目前的认识.内容比较杂,先亮一下目录,如图0-1. 标图0-1 目录题 1什么是 ...
- 如何找实习单位(个人的一点经验)
发信人: NetBSD (BSD on amy platform), 信区: Intern 标 题: 如何找实习单位(个人的一点经验) 发信站: 水木社区 (Tue Mar 28 16:03:41 ...
- 赚钱副业项目:steam搬砖的一点经验
进入正文 首先向大家说明一下,玩这个steam游戏道具搬砖项目,不必非得会玩游戏. 到目前操作这个项目2年时间了,那么接下来谈谈自己的一点经验. 关于选品.出售上架的13条核心经验: 建议新手入场的时 ...
- 各路高手谈谈手工焊接贴片元件的方法、经验
2006-05-08 15:28:22 各路高手谈谈手工焊接贴片元件的方法.经验,所用工具 作者[王为之][duoduo][mudfish]© --- 摘自 C51BBS论坛 --- [王为之] 我也 ...
- 知乎嵌入式大杂烩:学习STM32的一点经验分享
前言 前两天在群里看到群友们在讨论学习STM32的话题,并且今天也有一位机械专业的准研究生也问了STM32的入门问题.正好我也有一点经验,所以试着分享一下这个话题.我也不是什么大神,只是一名普通的工程 ...
- 【Solr】 solr对拼音搜索和拼音首字母搜索的支持
问:对于拼音和拼音首字母的支持,当你在搜商品的时候,如果想输入拼音和拼音首字母就给出商品的信息,怎么办呢? 实现方式有2种,但是他们其实是对应的. 用lucene实现 1.建索引, 多建一个索引字段 ...
最新文章
- 自带数据线的迷你数显充电宝,旅途必备
- 超全的Go Http路由框架性能比较
- JavaScript 3D图表
- VC++ 中ListCtrl经验总结
- PHP算法根据周数获取开始结束日期
- 使用CountDownLatch来模拟马拉松比赛
- 树莓派 触摸屏_如何用树莓派搭建一个颗粒物(PM2.5)传感器
- 云南计算机一级c类基础知识,云南省大学计算机 一级C类 【多选题及答案】
- AlexNet,VGG,GoogleNet,ResNet
- Bitmap如何高效加载图片
- android内存泄漏原因分析,Android 内存泄漏案例分析总结(Handler)
- java学习随笔(三)
- NLP-文本分类(2)
- Keil 5模块化编程详细步骤
- 金融用计算机,CFA考试指定计算器使用攻略
- R语言从github安装recharts包
- 计算机类学术论文格式,学术论文的标准格式是什么
- Katana程序集列表
- debian设置IP
- 中职计算机教师考核工作总结,中职计算机教师教学工作总结
热门文章
- 【Windows10下.sh文件的运行】‘bash’ is not recognized as an internal or external command
- android的apk加壳工具对比
- php使用addons,think addons教程
- Python入门如何给自己写一个文字小游戏?一只小白的Python游戏
- windows下使用cmd命令文件批量重命名批量修改后缀重命名快捷键
- wince buid
- Android凉了也要看的面试题,2020年5月美团Android面试真题(三面
- uip-学习笔记(移植篇)
- cocos2dx在Android studio运行 以及在 Android 平台上使用 JavaScript 直接调用 Java 方法
- vs2017开发ActiveX(主讲OCX)(八)、添加常用方法