我有一组字符串。其中,2个或更多的组可能代表相同的事物。这些组应该以给定组中任何成员的方式存储,您可以高效地获取组中的其他成员。
所以给定这个初始集:["a","b1","b2","c1","c2","c3"]
,结果结构应该是["a",["b1","b2"],["c1","c2","c3"]]
,而Fetch(“b”)应该返回["b1","b2"]
。
是否有用于此目的的特定数据结构和/或算法?
编辑:“b1”和“b2”不是实际字符串,它们表示2属于同一组。否则Trie将是一个完美的契合。
答案 0 :(得分:1)
我可能误解了最初的问题设置,但我相信使用现成的数据结构可以解决这个问题。从高层次来看,这个想法是创建一个从字符串到字符串集的映射。地图中的每个键都将与它等于的字符串集相关联。假设组中的每个字符串都映射到同一组字符串,这可以在时间和空间上有效地完成。
算法可能如下所示:
该算法和结果数据结构非常有效。假设您已经事先知道了集群,这个过程(使用trie作为映射的实现和一个简单的列表作为集合的数据结构)要求您访问每个输入字符串的每个字符两次 - 插入时一次假设你正在进行深层复制,它将它添加到trie中并将其添加到等于它的字符串集合中。因此,这是一种O(n)算法。
此外,查找速度非常快 - 找到等于某个字符串的字符串集,只需遍历trie找到字符串,查找相关的字符串集,然后迭代它。这需要O(L + k)时间,其中L是字符串的长度,k是匹配的数量。
希望这会有所帮助,如果我误解了问题陈述,请告诉我!
答案 1 :(得分:1)
由于这是Java,我会使用HashMap<String, Set<String>>
。这会将每个字符串映射到其等价集(包含该字符串以及属于同一组的所有其他字符串)。如何从输入构造等价集取决于您如何定义“等效”。如果输入按组排序(但实际上没有分组),并且如果您实现了一个谓词以测试等效性,那么您可以执行以下操作:
boolean differentGroups(String a, String b) {
// equivalence test (must handle a == null)
}
Map<String, Set<String>> makeMap(ArrayList<String> input) {
Map<String, Set<String>> map = new HashMap<String, Set<String>>();
String representative = null;
Set<String> group;
for (String next : input) {
if (differentGroups(representative, next)) {
representative = next;
group = new HashSet<String>();
}
group.add(next);
map.put(next, group);
}
return map;
}
请注意,仅当组是输入中的连续元素时才有效。如果他们不是,你需要更复杂的簿记来建立小组结构。