Java中基于部分单词匹配的字符串相似度比较及排序实现咨询
基于部分单词匹配的字符串排序实现(Java)
咱们先从你的需求里明确核心规则,这样实现起来更精准:
- 匹配逻辑:把搜索字符串拆成独立单词,目标字符串里的任意单词只要包含某个搜索词(比如
super能匹配superdupercold),就算该搜索词被命中; - 排序优先级:
- 第一优先级:匹配到的不同搜索词数量(从多到少)——比如你的例子里C匹配3个,A匹配2个,所以C排在A前面;
- 第二优先级:目标字符串的匹配率(匹配的目标单词数/目标总单词数,从高到低)——比如D和B都匹配1个搜索词,但D的匹配率是100%,B是50%,所以D排在B前面。
下面用Java的Stream API、正则和集合来实现,代码简洁且易扩展:
完整代码示例
import java.util.*; import java.util.stream.Collectors; public class PartialWordMatchSorter { public static void main(String[] args) { // 目标字符串列表 List<String> targetStrings = Arrays.asList( "white snow ball", "super exciting", "white image superdupercold", "cold" ); // 测试用例1:你提到的多词搜索 String searchQuery = " super cold white snow "; // 测试用例2:单词搜索 // String searchQuery = "super"; // 预处理搜索词:转小写、去重、过滤空字符串(支持大小写不敏感匹配) Set<String> searchWords = Arrays.stream(searchQuery.toLowerCase().split("\\s+")) .filter(word -> !word.isEmpty()) .collect(Collectors.toSet()); // 执行排序 List<String> sortedResults = targetStrings.stream() .sorted((s1, s2) -> { MatchMetrics metrics1 = calculateMatchMetrics(s1, searchWords); MatchMetrics metrics2 = calculateMatchMetrics(s2, searchWords); // 先按匹配的搜索词数量降序 int countCompare = Integer.compare(metrics2.matchedSearchWordCount, metrics1.matchedSearchWordCount); if (countCompare != 0) { return countCompare; } // 数量相同时,按匹配率降序 return Double.compare(metrics2.matchRate, metrics1.matchRate); }) .collect(Collectors.toList()); // 输出结果 System.out.println("排序结果:"); sortedResults.forEach(System.out::println); } // 封装匹配指标的内部类,让逻辑更清晰 private static class MatchMetrics { int matchedSearchWordCount; // 匹配到的不同搜索词数量 double matchRate; // 匹配的目标单词数/目标总单词数 } // 计算单个目标字符串的匹配指标 private static MatchMetrics calculateMatchMetrics(String target, Set<String> searchWords) { MatchMetrics metrics = new MatchMetrics(); // 拆分目标字符串为小写单词,过滤空字符串 List<String> targetWords = Arrays.stream(target.toLowerCase().split("\\s+")) .filter(word -> !word.isEmpty()) .collect(Collectors.toList()); int totalTargetWords = targetWords.size(); if (totalTargetWords == 0) { metrics.matchedSearchWordCount = 0; metrics.matchRate = 0.0; return metrics; } // 统计匹配的搜索词和目标单词数量 Set<String> matchedSearchWords = new HashSet<>(); int matchedTargetWordCount = 0; for (String targetWord : targetWords) { boolean isMatched = false; for (String searchWord : searchWords) { // 核心匹配逻辑:目标单词包含搜索词(可按需修改为全词/前缀匹配) if (targetWord.contains(searchWord)) { matchedSearchWords.add(searchWord); isMatched = true; } } if (isMatched) matchedTargetWordCount++; } metrics.matchedSearchWordCount = matchedSearchWords.size(); metrics.matchRate = (double) matchedTargetWordCount / totalTargetWords; return metrics; } }
代码说明
- 搜索词预处理:用
split("\\s+")拆分任意空白字符,转小写实现大小写不敏感匹配(如果需要大小写敏感,去掉toLowerCase()即可),用Set去重避免重复计算同一个搜索词; - 匹配逻辑可扩展:如果需要改成全词匹配,把
targetWord.contains(searchWord)换成targetWord.equals(searchWord)即可;改成前缀匹配则换成targetWord.startsWith(searchWord); - 排序逻辑贴合需求:完全按照你给出的例子规则排序,第一优先级是匹配的搜索词数量,第二是匹配率。
测试结果
- 当搜索词为
" super cold white snow "时,输出顺序:
和你预期的C、A、D、B完全一致;white image superdupercold white snow ball cold super exciting - 当搜索词为
"super"时,输出顺序:
符合你要求的B、C排序逻辑。super exciting white image superdupercold
内容的提问来源于stack exchange,提问作者user1314404
相关产品推荐
相关产品推荐

