查找字典

时间:2015-05-17 08:41:02

标签: algorithm

在程序中,我需要有效地回答以下形式的查询:

给定一组字符串A和查询字符串q返回所有s∈A使得s是q的子序列 例如,给定A = {" abc"," aaa"," abd"}和q =" abcd"," ABC"和" abd"应该退还。

有没有比迭代A的每个元素并检查它是否是q的子序列更好的方法?

注意:我考虑过STRIPS计划程序或自动计划程序。 STRIPS计划者中的每个州都是一组命题,如{"(房间罗马)","(at-robby rooma)","(at ball1 rooma)& #34;}。我想找到适用于特定州的所有基本行动。 STRIPS规划器中的操作基本上由两部分组成,前提条件和效果(这里并不真正相关)。前提条件是将一个动作应用于一个状态所需的一系列命题。例如,要应用动作"(移动rooma roomb)",其前提条件,{"(房间rooma)","(房间b)", "(at-robby rooma)"}必须在州内都是真的。

1 个答案:

答案 0 :(得分:0)

如果您的 A 集很大并且您有很多查询,那么您可以实现trie-like structure,其中 n 级别是指字符 n < / em>在一个字符串中。在您的示例中:

trie = {
    a: {
        a: {
             a: { value: "aaa"}
        },
        b {
             c: { value: "abc"},
             d: { value: "abd"}
        }        
    }
}

这将使您能够通过trie在分叉路径中查找匹配项:

function query(trie, q) {
    s = Set();

    if (q.isEmpty()) {
        if (trie.value) s.add(t.value);
    } else {
        s = s.union(query(trie, q[1:]));

        c = substr(q, 0, 1);
        if (t[c]) {
            s = s.union(query(t[c], substr(q, 1));
        }
    }
    return s;
}

有效地,您将生成 m 字符的问题字符串的所有2 ^ m 子集,但实际上,trie是稀疏的,您最终会检查更少的路径

速度回报伴随着许多查找。构建trie比执行暴力查找更昂贵。但是,如果您在更新集合 A 时只构建了一个trie或者有更新trie的方法,那么您将获得良好的查找性能。

trie节点的实际数据结构取决于项目可能具有的元素数量。在您的示例中,仅使用四个字母。如果您的“字母”范围有限,则可以使用数组。否则你可能需要一种字典,这可能会使树在内存中占据相当大的比例。