【问题标题】:Data structure for holding sets of interchangeable strings用于保存可互换字符串集的数据结构
【发布时间】:2011-12-31 16:33:00
【问题描述】:

我有一组字符串。其中,2个或更多的组可能代表相同的事物。这些组应该以给定组的任何成员的方式存储,您可以高效地获取组的其他成员。

所以给定这个初始集合:["a","b1","b2","c1","c2","c3"],结果结构应该类似于["a",["b1","b2"],["c1","c2","c3"]],Fetch("b") 应该返回["b1","b2"]

是否有用于此目的的特定数据结构和/或算法?

编辑:“b1”和“b2”不是实际的字符串,它们表示 2 属于同一组。否则,Trie 将是完美的选择。

【问题讨论】:

  • 这是一个特定的编程语言编程问题吗?如果不是,这可能属于计算机科学 stackexchange 而不是这里。如果您确实提到了特定的编程问题和语言,请相应地编辑
  • 听起来像disjoint-set forests 但倒过来了...
  • 你能说出你的确切问题吗,目前不清楚你的组是什么?
  • @SaeedAmiri 组是预定义的。因此,例如已知字符串“b1”和“b2”在构建结构时属于同一组。
  • 告诉我们两个字符串属于同一个组的标准是什么?如果就像查看字符串是否具有某个前缀/后缀/子字符串/结构一样简单,您可以简单地将它们组合在一起,通过列表一次遍历。如果它更像是字符串对之间的一组关系,则需要将其建模为图形并运行 bfs/dfs 或使用不相交的集合对它们进行分组。

标签: java algorithm data-structures graph-algorithm


【解决方案1】:

我可能误解了最初的问题设置,但我相信使用现成的数据结构可以简单而优雅地解决这个问题。这个想法是,在高层次上,创建一个从字符串到字符串集的映射。映射中的每个键都将与其对应的字符串集相关联。假设组中的每个字符串都映射到同一组字符串,这可以节省时间和空间。

算法可能如下所示:

  1. 构造一个从字符串到字符串集的映射 M。
  2. 将所有彼此相等的字符串组合在一起(此步骤取决于字符串和组的指定方式)。
  3. 对于每个集群:
    1. 在该集群中创建一组规范的字符串。
    2. 将每个字符串作为键添加到映射中,其值为规范集。

这个算法和产生的数据结构是相当有效的。假设您已经提前知道了集群,这个过程(使用 trie 作为映射的实现和一个简单的列表作为集合的数据结构)需要您准确地访问每个输入字符串的每个字符两次 - 插入时一次假设您正在制作深层副本,则将其放入 trie 并在将其添加到与其相等的字符串集中时一次。因此这是一个 O(n) 算法。

此外,查找非常快——要找到与某个字符串相等的字符串集,只需遍历特里树即可找到该字符串,查找相关的字符串集,然后对其进行迭代。这需要 O(L + k) 时间,其中 L 是字符串的长度,k 是匹配的数量。

希望这会有所帮助,如果我误解了问题陈述,请告诉我!

【讨论】:

    【解决方案2】:

    由于这是 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;
    }
    

    请注意,这仅在组是输入中的连续元素时才有效。如果不是,您将需要更复杂的簿记来构建组结构。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-26
      • 2015-02-21
      • 1970-01-01
      • 2011-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-16
      相关资源
      最近更新 更多