T9 算法太慢
T9 Algorithm too slow
我正在尝试为我的 android dialer 实施 T9。但它滞后。我检查并生成可能组合的列表是轻松的。
但我正在尝试使用一种模式进行匹配,我生成的模式如下
Pattern queryPattern;
List<String> names = T9Utils.possibleNames(query);
StringBuilder sb = new StringBuilder();
for (String name : names) {
Matcher m = p.matcher(name.toLowerCase());
sb.append("(");
sb.append(m.replaceAll("([=10=])\s*"));
sb.append(")");
if (!name.equals(names.get(names.size() - 1))) {
sb.append("|");
}
}
queryPattern = Pattern.compile("(?i).*(" + sb.toString() + ").*");
for (CallLogItem contact : allContacts) {
Matcher nameM = queryPattern.matcher(contact.displayName);
Matcher phoneM = queryPattern.matcher(contact.phoneNumber);
if (nameM.matches()) {
//TODO: Highlighting
toBeDisplayed.add(contact);
} else if (phoneM.matches()) {
toBeDisplayed.add(contact);
}
}
生成的模式类似于
(?i).*(((g)\s*(d)\s*)|((g)\s*(e)\s*)|((g)\s*(f)\s*)|((g)\s*(3)\s*)|((h)\s*(d)\s*)|((h)\s*(e)\s*)|((h)\s*(f)\s*)|((h)\s*(3)\s*)|((i)\s*(d)\s*)|((i)\s*(e)\s*)|((i)\s*(f)\s*)|((i)\s*(3)\s*)|((4)\s*(d)\s*)|((4)\s*(e)\s*)|((4)\s*(f)\s*)|((4)\s*(3)\s*)).*
首先,您应该使用字符 class 而不是所有这些交替。
然后删除要比较的字符串的空格。以你的名字为例:Amanuel Nega
=> AmanuelNega
。您应该使用此转换 table(根据需要进行调整):
Input | Corresponding class
---------------------------
1 | [1.!]
2 | [2abc]
3 | [3def]
4 | [4ghi]
5 | [5klm]
6 | [6nop]
7 | [7qrst]
8 | [8uvw]
9 | [9xyz]
0 | [0+]
假设我输入 4
,然后输入 3
(这是您的输出建议的内容)。
那么输出将是[4ghi][3def]
。
如果我想匹配 AmanuelNega
我必须输入 2526835
这将产生正则表达式:
[2abc][5klm][2abc][6nop][8uvw][3def][5klm]
这将比您已有的快得多
我正在尝试为我的 android dialer 实施 T9。但它滞后。我检查并生成可能组合的列表是轻松的。
但我正在尝试使用一种模式进行匹配,我生成的模式如下
Pattern queryPattern;
List<String> names = T9Utils.possibleNames(query);
StringBuilder sb = new StringBuilder();
for (String name : names) {
Matcher m = p.matcher(name.toLowerCase());
sb.append("(");
sb.append(m.replaceAll("([=10=])\s*"));
sb.append(")");
if (!name.equals(names.get(names.size() - 1))) {
sb.append("|");
}
}
queryPattern = Pattern.compile("(?i).*(" + sb.toString() + ").*");
for (CallLogItem contact : allContacts) {
Matcher nameM = queryPattern.matcher(contact.displayName);
Matcher phoneM = queryPattern.matcher(contact.phoneNumber);
if (nameM.matches()) {
//TODO: Highlighting
toBeDisplayed.add(contact);
} else if (phoneM.matches()) {
toBeDisplayed.add(contact);
}
}
生成的模式类似于
(?i).*(((g)\s*(d)\s*)|((g)\s*(e)\s*)|((g)\s*(f)\s*)|((g)\s*(3)\s*)|((h)\s*(d)\s*)|((h)\s*(e)\s*)|((h)\s*(f)\s*)|((h)\s*(3)\s*)|((i)\s*(d)\s*)|((i)\s*(e)\s*)|((i)\s*(f)\s*)|((i)\s*(3)\s*)|((4)\s*(d)\s*)|((4)\s*(e)\s*)|((4)\s*(f)\s*)|((4)\s*(3)\s*)).*
首先,您应该使用字符 class 而不是所有这些交替。
然后删除要比较的字符串的空格。以你的名字为例:Amanuel Nega
=> AmanuelNega
。您应该使用此转换 table(根据需要进行调整):
Input | Corresponding class
---------------------------
1 | [1.!]
2 | [2abc]
3 | [3def]
4 | [4ghi]
5 | [5klm]
6 | [6nop]
7 | [7qrst]
8 | [8uvw]
9 | [9xyz]
0 | [0+]
假设我输入 4
,然后输入 3
(这是您的输出建议的内容)。
那么输出将是[4ghi][3def]
。
如果我想匹配 AmanuelNega
我必须输入 2526835
这将产生正则表达式:
[2abc][5klm][2abc][6nop][8uvw][3def][5klm]
这将比您已有的快得多