java - 从给定字符串中匹配次数最多的列表中提取项目
问题描述
我的应用程序中有 2 个数组列表。第一个数组列表是包含问题列表的对象类型。现在这个问题列表有一个名为"Keywords"的字段。这是一个字符串,但可以包含逗号分隔的关键字。
现在我有一个文本字段,用户可以根据这些关键字搜索问题。我面临的问题是我想根据关键字匹配的数量从问题列表中过滤掉问题。
例如。用户在搜索文本字段中输入了 3 个逗号分隔的关键字。我现在想要的是如果所有 3 个关键字都与问题列表中的某个值匹配,那么我必须只返回这些元素。这部分很简单,我可以做到。
但是,如果我们在列表中没有得到任何完全匹配,那么我必须找到具有最大关键字匹配的项目,即如果逗号分隔的字符串中的 3 个关键字中的 2 个与列表中的某个项目匹配,那么我有将该项目作为结果返回。
存储在列表中的值:-
a) Hi, Hello, Hola, Bonjour.
b) Hi, Hello
c) Hi
在搜索文本中输入的值:-
Hi, Hello, Hola
现在作为回应,我只想要第一个元素,因为它有 3 个关键字与用户输入的内容相匹配。我无法弄清楚如何做到这一点。此外,我正在从 sqlite 数据库中获取这个问题列表,所以如果这可以通过一些 sql 查询来完成,那么我也准备好了。
这是我当前的过滤方法代码
public ArrayList<QuestionAnswerModal> filter(String keyword,boolean isQuestionSearch) {
ArrayList<QuestionAnswerModal> arrayList = new ArrayList<>();
if (!isQuestionSearch) {
for (QuestionAnswerModal modal : questionAnswerArrayList) {
if (modal.getKeyword().equalsIgnoreCase(keyword)) {
arrayList.add(modal);
}else{
ArrayList<String> keywords=new ArrayList<>();
String[]word=modal.getKeyword().split(",");
}
}
if (arrayList.size() > 0) {
System.out.print("list size "+arrayList.size());
} else {
System.out.print("No records found");
}
return arrayList;
}else{
for (QuestionAnswerModal modal : questionAnswerArrayList) {
if (modal.getQuestion().equalsIgnoreCase(keyword)) {
arrayList.add(modal);
}
}
if (arrayList.size() > 0) {
System.out.print("list size "+arrayList.size());
} else {
System.out.print("No records found");
}
return arrayList;
}
}
解决方案
我把它留给你作为一个练习来弄清楚这个解决方案是如何工作的,但是你可以随意提出任何问题。
Java 7 解决方案:
import java.util.*;
import static org.apache.commons.lang3.StringUtils.trimToEmpty;
public class MaxMatchFinder {
public static void main(String[] args) {
Map<String, Set<String>> tagsByName = new HashMap<>();
tagsByName.put("a", new HashSet<>(Arrays.asList("Hi", "Hello", "Hola", "Bonjour")));
tagsByName.put("b", new HashSet<>(Arrays.asList("Hi", "Hello")));
tagsByName.put("c", new HashSet<>(Arrays.asList("Hi")));
String searchText = "Hi, Hello, Hola";
String[] tagsToFind = searchText.split(",");
Map<String, Integer> matchCountsByEntryName = new HashMap<>();
for (String tagToFind : tagsToFind) {
for (String entryName : tagsByName.keySet()) {
Set<String> tags = tagsByName.get(entryName);
if (tags.contains(trimToEmpty(tagToFind))) {
Integer count = matchCountsByEntryName.get(entryName);
Integer incrementedCount = count == null ? 1 : count + 1;
matchCountsByEntryName.put(entryName, incrementedCount);
}
}
}
List<Map.Entry<String, Integer>> sortedEntries = new ArrayList<>(matchCountsByEntryName.entrySet());
Collections.sort(sortedEntries, new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Map.Entry<String, Integer> e1, Map.Entry<String, Integer> e2) {
return e2.getValue().compareTo(e1.getValue());
}
});
Map.Entry<String, Integer> entryWithMostMatches = sortedEntries.get(0);
System.out.printf("Of the entries to be searched," +
" entry \"%s\" contains the most matches (%d).\n",
entryWithMostMatches.getKey(), entryWithMostMatches.getValue());
}
}
Java 8 解决方案:
import java.util.*;
import java.util.stream.Collectors;
import static org.apache.commons.lang3.StringUtils.trimToEmpty;
public class MaxMatchFinder {
public static void main(String[] args) {
Map<String, Set<String>> tagsByName = new HashMap<>();
tagsByName.put("a", new HashSet<>(Arrays.asList("Hi", "Hello", "Hola", "Bonjour")));
tagsByName.put("b", new HashSet<>(Arrays.asList("Hi", "Hello")));
tagsByName.put("c", new HashSet<>(Arrays.asList("Hi")));
String searchText = "Hi, Hello, Hola";
String[] tagsToFind = searchText.split(",");
Map<String, Integer> matchCountsByEntryName = new HashMap<>();
Arrays.stream(tagsToFind)
.forEach(tagToFind -> {
for (String entryName : tagsByName.keySet()) {
Set<String> tags = tagsByName.get(entryName);
if (tags.contains(trimToEmpty(tagToFind))) {
matchCountsByEntryName.compute(entryName, (k, v) -> v == null ? 1 : v + 1);
}
}
});
List<Map.Entry<String, Integer>> sortedEntries = matchCountsByEntryName.entrySet().stream()
.sorted((e1, e2) -> e2.getValue().compareTo(e1.getValue()))
.collect(Collectors.toList());
Map.Entry<String, Integer> entryWithMostMatches = sortedEntries.get(0);
System.out.printf("Of the entries to be searched," +
" entry \"%s\" contains the most matches (%d).\n",
entryWithMostMatches.getKey(), entryWithMostMatches.getValue());
}
}
推荐阅读
- typescript - Prisma - 使用时仅返回子对象字段
- postgresql - 嵌套`declare...begin...end`中的%rowtype
- dns - 木材和 WPML 的翻译问题(Wordpress,每个域的不同语言)
- excel - SCript 不会为每个过滤值生成新的工作簿
- html - VS Code 添加新字体 HTML
- node.js - 使用 node.js 工作线程“横向扩展”socket.io
- go - 当 nodejs 成功时,Google Cloud API Speech-to-text Go 程序返回“提供的范围未授权”
- json - 添加对“manifest.json”的评论
- hibernate - 无法在 JPA 实体中使用 Kotlins 值类
- node.js - Joi 使一系列数字无效