Есть набор предложений по типу "Green Apple", и каждое имеет от 2 до 7 слов. Нужно находить среди них к примеру "Green Apple" по таким ключевым словам как "gra" или "gap". Как это можно сделать?
Мне кажется, тут оптимальней использовать Trie. Например, есть класс
public class TrieNode {
private HashMap<Character, TrieNode> _children = new HashMap<>();
private String _payload = null;
}
Он хранит текущее слово и подузлы, где каждый подузел асоциирован с символом. Далее, напишем для класса функцию добавления слова
public void add(String str) {
add(str, 0);
}
private void add(String str, int ind) {
if (str.length() == ind) {
_payload = str;
return;
}
Character c = str.charAt(ind);
c = Character.toLowerCase(c);
if (_children.containsKey(c)) _children.get(c).add(str, ind + 1);
else {
TrieNode next = new TrieNode();
_children.put(c, next);
next.add(str, ind + 1);
}
}
Функцию поиска по паттерну
public ArrayList<String> retrieve(String filter) {
ArrayList<String> result = new ArrayList<>();
retrieve(filter.toLowerCase(), 0, result);
return result;
}
private void retrieve(String filter, int index, ArrayList<String> result) {
if (index < filter.length()) {
Character current = filter.charAt(index);
for (Character c : _children.keySet()) {
if (c.equals(current)) _children.get(c).retrieve(filter, index + 1, result);
else _children.get(c).retrieve(filter, index, result);
}
}
if (index >= filter.length()) {
if (_payload != null) result.add(_payload);
for (TrieNode n : _children.values()) n.retrieve(filter, index, result);
}
}
Как это все тестировать
public static void main(String[] args) {
TrieNode root = new TrieNode();
root.add("Green Apple");
root.add("Bla bla bla");
root.add("StackOverflow");
ShowSearchResultFor(root, "gra");
ShowSearchResultFor(root, "gap");
ShowSearchResultFor(root, "sof");
ShowSearchResultFor(root, "bbb");
ShowSearchResultFor(root, "a");
}
private static void ShowSearchResultFor(TrieNode root, String filter){
System.out.println();
System.out.println("results for: " + filter);
for(String ret : root.retrieve(filter)){
System.out.println(ret);
}
}
Вывод в консоль ожидаем
results for: gra
Green Apple
results for: gap
Green Apple
results for: sof
StackOverflow
results for: bbb
Bla bla bla
results for: a
Bla bla bla
StackOverflow
Green Apple
Более лаконичный, но вероятно (не проверял) более медленнный подход
private static void ShowSearchResultFor(String[] words, String filter){
filter = filter.toLowerCase();
System.out.println();
System.out.println("results for: " + filter);
for(String w : words){
int ind = 0;
for(Character cw : w.toLowerCase().toCharArray()){
if (cw.equals(filter.charAt(ind))) ind++;
if (ind >= filter.length()){
System.out.println(w);
break;
}
}
}
}
как проверить
public static void main(String[] args) {
String[] words = new String[3];
words[0] = "Green Apple";
words[1] = "Bla bla bla";
words[2] = "StackOverflow";
ShowSearchResultFor(words, "gra");
ShowSearchResultFor(words, "gap");
ShowSearchResultFor(words, "sof");
ShowSearchResultFor(words, "bbb");
ShowSearchResultFor(words, "a");
ShowSearchResultFor(words, "StackOverflow");
}
Вывод
results for: gra
Green Apple
results for: gap
Green Apple
results for: sof
StackOverflow
results for: bbb
Bla bla bla
results for: a
Green Apple
Bla bla bla
StackOverflow
results for: stackoverflow
StackOverflow
Вангую, что самый медленный способ с регулярками
private static void ShowSearchResultFor(String[] words, String filter){
filter = filter.toLowerCase();
System.out.println();
System.out.println("results for: " + filter);
StringBuffer buffer = new StringBuffer();
for(Character c : filter.toCharArray()){
buffer.append(c);
buffer.append(".*");
}
Pattern p = Pattern.compile(buffer.toString());
for(String w : words){
Matcher m = p.matcher(w.toLowerCase());
if (m.find()) System.out.println(w);
}
}
Как проверить
public static void main(String[] args) {
String[] words = new String[3];
words[0] = "Green Apple";
words[1] = "Bla bla bla";
words[2] = "StackOverflow";
ShowSearchResultFor(words, "gra");
ShowSearchResultFor(words, "gap");
ShowSearchResultFor(words, "sof");
ShowSearchResultFor(words, "bbb");
ShowSearchResultFor(words, "a");
ShowSearchResultFor(words, "StackOverflow");
}
Вывод
results for: gra
Green Apple
results for: gap
Green Apple
results for: sof
StackOverflow
results for: bbb
Bla bla bla
results for: a
Green Apple
Bla bla bla
StackOverflow
results for: stackoverflow
StackOverflow
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
решил поработать с командной строкой в javaНашел способ работы с cmd через ProcessBuilder
Описание поля сущности:
Есть кастомный ListView, каждый Item содержит Button