Outlook的联系人查找,不支持用拼音的模糊查找,于是自己想实现一个。需求如下:
要求
允许模糊音,比如(zh,z),(ing, in)
允许每个字的模糊匹配,字之间不能用空格
比如:
字符串"Nokia客户服务中心",先拆开成拼音为:Nokia Ke Hu Fu Wu Zhong Xing ,拼音的总长为22
每个字再拆开后,表示为下表(第一行是标题),注意空也算一个字的组合之一
标题 | Nokia | 客 | 户 | 服 | 务 | 中 | 心 |
1 | n | k | h | f | w | z | x |
2 | no | ke | hu | fu | wu | zo | xi |
3 | nok | zon | xin | ||||
4 | noki | zong | |||||
5 | nokia | zh | |||||
6 | zho | ||||||
7 | zhon | ||||||
8 | zhong | ||||||
合计 | 6 | 3 | 3 | 3 | 3 | 9 | 5 |
目标:使用所有字的任意组合,都能匹配到字符串Nokia客户服务中心。也就是说有 6 * 3 * 3 * 3 * 3 * 9 * 5 = 21870种组合可以匹配,每一种组合会有相应的权重,计算公式为:
权重(组合串) = 组合串的长度 / 拼音的总长度
可能表达的不是很清楚,以下随意举例可能的匹配(以*间隔是为了说明,实际输入时不应该有*)
组合串 | 组合串的长度 | 组合串的权重 |
n*ke*h*f*wu*zho*xi | 12 | 12 / 22 |
nok*k*hu*f*w*z*x | 10 | 10 / 22 |
n*k*h*f*w*z*x | 7 | 7 / 22 |
本以为不难,但真的做起来发现算法的效率是个大问题,一开始没有仔细想,就是简单的把所有组合作了散列,一运行发现在散列时相当慢,仔细一看才发现有些联系人的组合数量是相当惊人,比如举的例子,达到了21870种。
说来惭愧,对数据结构和算法实在是不济,一时间就想不出复杂度在O(1)或O(log n)的算法。在此抛砖引玉,希望和大家讨论。
========这是无敌的分割线=============
以下是做这个事情过程中的一些工具代码,很简单,与大家分享
-
汉字转拼音
程序很简单,就是使用码表,因为只是作为工具,我没有做任何优化。
下载ChineseSpell.cs