完整源码在我的github上 https://github.com/NashLegend/QuicKid
智能拨号是指,呃不用解释了,国内拨号软件都带的大家都知道,就是输入姓名拼音的一部分就可快速搜索出联系人的拨号方式。如下图
智能匹配,很容易想到的就是先把九宫格输入键盘上输入的数字转换成可能的拼音组合,然后再用这些可能的拼音与联系人列表中的姓名拼音一一匹配,取匹配度最高的排到最前,但是这有一个问题就是数组对应的可能的拼音组合实在是点儿多,跑一下下面的代码就知道了。如果想智能一些的话还要先剔除一些不可能的拼音组合实在有点麻烦。
public static HashMap<Character, String[]> keyMaps;
public static void main(String[] args) {
keyMaps = new HashMap<Character, String[]>();
keyMaps.put('0', new String[0]);
keyMaps.put('1', new String[0]);
keyMaps.put('2', new String[] { "a", "b", "c" });
keyMaps.put('3', new String[] { "d", "e", "f" });
keyMaps.put('4', new String[] { "g", "h", "i" });
keyMaps.put('5', new String[] { "j", "k", "l" });
keyMaps.put('6', new String[] { "m", "n", "o" });
keyMaps.put('7', new String[] { "p", "q", "r", "s" });
keyMaps.put('8', new String[] { "t", "u", "v" });
keyMaps.put('9', new String[] { "w", "x", "y", "z" });
List<String> lss = getPossibleKeys("726");
System.out.println(lss.size());
}
public static ArrayList<String> getPossibleKeys(String key) {
ArrayList<String> list = new ArrayList<String>();
if (key.length() > 0) {
if (key.contains("1") || key.contains("0")) {
list.add(key);
} else {
int keyLen = key.length();
String[] words;
if (keyLen == 1) {
words = keyMaps.get(key.charAt(0));
for (int i = 0; i < words.length; i++) {
list.add(words[i]);
}
} else {
ArrayList<String> sonList = getPossibleKeys(key.substring(
0, key.length() - 1));
words = keyMaps.get(key.charAt(key.length() - 1));
for (int i = 0; i < words.length; i++) {
for (Iterator<String> iterator = sonList.iterator(); iterator
.hasNext();) {
String sonStr = iterator.next();
list.add(sonStr + words[i]);
}
}
}
}
}
return list;
}
所以可以反过来想,为什么一定要匹配拼音呢。其实我们可以匹配数字,将姓名的拼音转化成九宫格上的数字,比如张三就是94264,726。用输入的数字来匹配这些数字,匹配次数将大大减少。匹配出的数值越高,匹配度越强。
下面先定义一下几个匹配规则
-
完全匹配。用来匹配姓名和电话号码。指输入字符串与联系人内某一匹配项完全匹配。无加减分项。
PanZhiHui-->PanZhiHui
-
前置首字母完全匹配。用来匹配姓名。指输入字符串与联系人前几个首字母完全匹配。用来匹配姓名。是前置首字母溢出匹配的特殊形式。 无加分项,减分项为不匹配的首字母个数。
PZH-->PanZhiHui
。+2-0
PZ-->PanZhiHui
。+2-1 -
前置首字母溢出匹配。用来匹配姓名。指在匹配首字母的情况下,还匹配了某一个或者几个首字母后一段连贯的字符串。加分项为匹配到的首字母个数,减分项为不匹配的首字母个数。
PanZH-->PanZhiHui
。+1-0
PZhiHui-->PanZhiHui
。+1-0
PZHui-->PanZhiHui
。+1-0
PZHu-->PanZhiHui
。+1-0
PZhi-->PanZhiHui
。+1-1 -
前置段匹配。用来匹配姓名。指一个长度为N的连贯字符与联系人内某一匹配项的前N个字符完全匹配。是前置首字母溢出匹配的特殊形式。
panzh-->PanZhiHui
-
后置首字母完全匹配。用来匹配姓名。指输入字符串匹配除第一个首字母以外的其他几个连续首字母。 无加分项,减分项为不匹配的首字母个数。
ZH-->PanZhiHui
-
后置首字母溢出匹配。用来匹配姓名。后置首字母完全匹配的情况下,还匹配了某一个或者几个首字母后一段连贯的字符串。加分项为匹配的首字母的数量,减分项为不匹配的首字母个数。
ZHu-->PanZhiHui
。+1-0
Zh-->PanZhiRui
。+1-1 -
后置段匹配。用来匹配姓名。指有一串长度为N的连贯字符与与联系人内某一匹配项的后半部的一段N个字符串匹配,且此连贯字符的开头位置必须是某一首字母位置。是后置首字母溢出匹配的特殊形式,同时意味着后置首字母溢出匹配事实上不需要加分项,只要保证后置首字母完全匹配的加分项比它大就足够了。