一、 拼音检查

来源:互联网 发布:qq国际网络加速器 编辑:程序博客网 时间:2024/05/01 19:31


拼音检查包括拼音与拼音缩写两个模块。

 

 

 

拼音检查:

拼音检查设计图

1) 词库来源

词库来源在数据库中,以方便扩展,只要每天都会产生一个当天日期相关的搜索词库表,包含相关信息

2) 建立索引

因为一个拼音是对应多个中文词的,所以建立个数据结构,以ConCurrentHashMap<String,CopyOnWriteArrayList<integer>>的形式,存放在内存中,以便快速查询。

中文转化相应的拼写,使用第三方包pinyin4j,将中文转换为相应的拼音与拼音缩写。

比如:中国-> zhongguo, zhong guo, zg(拼音缩写)

相应的索引结构为:

Zhongguo->中国(文档ID)

//Zhong guo ->中国(文档ID)

Zg-> 中国(文档ID)

3) 检查并返回结果

用户输入拼音,zhongguo

通过Map找到对应的中文集合,其中以某个权重来排序(可能是以搜索量),并返回某个数量的结果,结果以字符串数组形式返回。

 

 当有多个拼查组成的时候 ,先将其各自分开,然后采用正向最大匹配或者,反向最大匹配获得最佳的结果。

比如输入的是:zhongguo ren

zhongguo ren-> zhong guo ren-> zhongguoren-》中国人

 

yizhenjianxie de-yi zhen jian xie de

 

yi zhen jian xie de-> yizhenjianxiede 找不到

yi zhen jian xie-yizhenjianxie->一针见血   (返回最大匹配)

中文检查包括中文纠错与汉字拼音纠错。

 

1) 词库来源:

词库来源在数据库中,以方便扩展,只要每天都会产生一个当天日期相关的搜索词库表,包含相关信息

2) 建立索引

采用二元循环切词:

“背天而驰”->”背天”,”天而”,”而驰”,”驰背”

以ConCurrentHashMap<String,CopyOnWriteArrayList<integer>>结构存储,其中String为元切出的两个中文字符,CopyOnWriteArrayList<integer>存储相应文档,文档有三个属性,数据结构如下:

/**

 * 唯一的标识

 */

private int id;

/**

 * 文档内容

 */

private String text;

/**

 * 搜索总数量

 */

private int freq;

例如:

词库为:ABCBCDA

下标 0        1 

DOC为:[0,”ABC”,0][1,”BCDA”,0] 

索引如下:

AB->[0]

BC->[0,1]

CA-> [0]

CD->[1]

DA->[1]

3) 检查并返回结果

粗匹配:

一元切词方法:

比如输入ABC->AB,BCCA 查找文档

AB->[0]

BC->[0,1]

CA-> [0]

合并结果为文档   [0,”ABC”,0][1,”BCD”,0] 

 

细匹配:

从查询结果中过滤掉自身

 中文拼写检查细匹配:

利用N-gram算法对拆分后的片段进行切分,记录候选关键词及词频

结果的排序优先级:

1. 搜索次数优先比较,普通词库中的搜索次数默认为0,搜索词库有记录。搜索次数越大,则表示越优先

2. 编辑距离为衡量:1表示两个字符串完全相同,0表示两个字符串具有最大的不相似程度

放入以搜索次数与编辑距离分数为衡量指标的堆中,堆的长度人为确定,具体根据要查询的建议单词的多少确定。

返回结果,注意此处的结果要是以编辑距离增序的结果(使用优先队列的函数可以达到此要求)。

跟关键词一样的词忽略,编辑距离太大也忽略。

返回排在前面的几个结果。

一、 索引管理

索引结构:ConcurrentHashMap 与CopyOnWriteArrayList相结合

 

ConcurrentHashMap 

摒弃了单一的 map 范围的锁,取而代之的是由 32 个锁组成的集合,其中每个锁负责保护 hash bucket 的一个子集。锁主要由变化性操作( put() 和 remove() )使用。具有 32 个独立的锁意味着最多可以有 32 个线程可以同时修改 map。这并不一定是说在并发地对 map 进行写操作的线程数少于 32 时,另外的写操作不会被阻塞――32 对于写线程来说是理论上的并发限制数目,但是实际上可能达不到这个值。但是,32 依然比 要好得多,而且对于运行于目前这一代的计算机系统上的大多数应用程序来说已经足够了

CopyOnWriteArrayList

 是ArrayList的一个线程安全的变体,其中所有可变操作(添加、设置,等等)都是通过对基础数组进行一次新的复制来实现的。 

这一般需要很大的开销,但是当遍历操作的数量大大超过可变操作的数量时,这种方法可能比其他替代方法更 有效。在不能或不想进行同步遍历,但又需要从并发线程中排除冲突时,它也很有用。快照风格的迭代器方法在创建迭代器时使用了对数组状态的引用。此数组在迭代器的生存期内绝不会更改,因此不可能发生冲突,并且迭代器保证不会抛出 ConcurrentModificationException。自创建迭代器以后,迭代器就不会反映列表的添加、移除或者更改。不支持迭代器上更改元素的操作(移除、设置和添加)。这些方法将抛出 UnsupportedOperationException。 

 

1. 索引创建

索引由无到有创建,在服务启动时运行,此时主要只有写,没有读,索引只有一份,中文拼写跟拼音检查共享一个索引,由一个单例模式的类管理。可以保证读取到的数据的唯一性,且索引由ConcurrentHashMap结构存储,可以允许多个写线程同时进行。

 

2. 索引更新

索引已存在,每天定时更新索引时,就会存在多读与写线程的存丰,此时,读的时候没有加锁,写的时候就会锁,但只是锁住ConcurrentHashMap中的某个片段,其它读写线程照样进行,提高更大的并发量。每一次更改某个key对应的CopyOnWriteArrayList时候,都会复制一个副本,所以旧数据并不会因为新增加数据而产生冲突。

 

二、 热度排名规则

每个关键词每天都有不一样的搜索量,所以每个词的热度并不能通过直接累加来计算它的热度大小。

1) 词的属性:词内容,词搜索量,累计出现天数,热度=词搜索量累加/累计出现天数,每个新词的累计天数开始置为1,当热度小于或等于0时,累计出现天数重新设置为1;

热度=(搜索总量)/出现的天数

排序的时候按热度大小排序。

建索引的时候直接从数据库中读取,由统计词库的表存储相关信息。

2) 黑词处理,在索引前去掉。

原创粉丝点击