Java中如何从多列表提取公共连续元素组?求实现方案
嘿,咱们一步步来解决这个问题。我知道你需要从多个List<String>中找出所有在至少两个列表里出现过的连续元素组,还要统计每个组出现在多少个列表中。先理清楚核心需求,然后咱们写一个靠谱的Java实现方案。
思路拆解
要实现这个需求,咱们可以分成三个核心步骤:
- 提取单个列表的所有唯一连续子序列:对每个列表,生成它包含的所有可能的连续元素组,并且去重(同一个列表里重复出现的组只算一次,比如列表c里的
hi出现两次,但只标记这个列表包含hi)。 - 全局统计子序列出现的列表数量:用一个Map来记录每个子序列对应的出现次数(key是子序列字符串,value是包含它的列表数)。
- 过滤并输出结果:筛选出出现次数≥2的子序列,按长度从长到短排序后输出,和你示例的展示逻辑一致。
Java代码实现
先写一个工具方法来生成单个列表的所有唯一连续子序列:
import java.util.*; public class CommonConsecutiveGroups { // 生成单个列表的所有唯一连续子序列 private static Set<String> getAllUniqueSubsequences(List<String> list) { Set<String> subsequences = new HashSet<>(); int listSize = list.size(); // 遍历每个起始位置 for (int startIdx = 0; startIdx < listSize; startIdx++) { StringBuilder sb = new StringBuilder(); // 从起始位置往后拼接,生成所有以startIdx开头的连续子序列 for (int endIdx = startIdx; endIdx < listSize; endIdx++) { sb.append(list.get(endIdx)); subsequences.add(sb.toString()); } } return subsequences; } public static void main(String[] args) { // 初始化你提供的示例列表 List<String> a = new ArrayList<>(List.of("a", "b", "c", "d", "e", "f", "g")); List<String> b = new ArrayList<>(List.of("a", "b", "c", "d", "f", "g")); List<String> c = new ArrayList<>(List.of("h", "i", "a", "b", "c", "h", "i")); // 把所有列表放到一个集合里统一处理 List<List<String>> allLists = List.of(a, b, c); // 统计每个子序列出现的列表数量 Map<String, Integer> subsequenceCountMap = new HashMap<>(); for (List<String> currentList : allLists) { Set<String> uniqueSubs = getAllUniqueSubsequences(currentList); for (String subseq : uniqueSubs) { // 累加计数:如果子序列已存在就+1,否则初始化为1 subsequenceCountMap.put(subseq, subsequenceCountMap.getOrDefault(subseq, 0) + 1); } } // 对结果排序:先按子序列长度降序,再按出现次数降序,让长的组优先显示 List<Map.Entry<String, Integer>> sortedResults = new ArrayList<>(subsequenceCountMap.entrySet()); sortedResults.sort((entry1, entry2) -> { int lengthCompare = Integer.compare(entry2.getKey().length(), entry1.getKey().length()); if (lengthCompare != 0) { return lengthCompare; } return Integer.compare(entry2.getValue(), entry1.getValue()); }); // 输出符合要求的结果(出现次数≥2) System.out.println("公共连续元素组:"); StringBuilder resultSb = new StringBuilder(); for (Map.Entry<String, Integer> entry : sortedResults) { if (entry.getValue() >= 2) { resultSb.append(entry.getKey()) .append("(在").append(entry.getValue()).append("个列表中出现)、"); } } // 去掉末尾多余的顿号 if (resultSb.length() > 0) { resultSb.setLength(resultSb.length() - 1); } System.out.println(resultSb); } }
代码说明
getAllUniqueSubsequences方法:通过双重循环生成所有连续子序列,用HashSet自动去重,避免同一个列表里重复的子序列被多次统计。- 统计逻辑:遍历每个列表的唯一子序列,在全局Map中更新计数,确保每个列表对同一个子序列只贡献一次计数。
- 排序与输出:按子序列长度降序排序,让长的连续组(比如
abc)先展示,和你示例的预期输出顺序一致;最后过滤掉出现次数小于2的条目,整理成清晰的输出格式。
注意点
你示例里提到的e其实只在列表a中出现,所以不会被包含在最终结果里,应该是写示例时的小失误~如果需要排除单个元素,可以在过滤时添加entry.getKey().length() > 1的条件。
内容的提问来源于stack exchange,提问作者Kalyan Talluri
相关产品推荐
相关产品推荐

