Алгоритм T9 слишком медленный
Я пытаюсь внедрить T9 в мой номеронабиратель Android. Но это отстает. Я проверил и создание списка возможных комбинаций безболезненно.
Но я пытаюсь сопоставить, используя шаблон, и я сгенерировал шаблон следующим образом
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("($0)\\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*)).*
1 ответ
Во-первых, вы должны использовать класс символов вместо всех этих чередований.
Затем удалите пробелы строки, с которой вы сравниваете. Возьмите свое имя в качестве примера: Amanuel Nega
=> AmanuelNega
, Вы должны использовать эту таблицу преобразования (адаптируйте ее по мере необходимости):
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]
Что будет намного быстрее, чем у вас уже есть