在程序中,我需要有效地回答以下形式的查询:
给定一组字符串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)"}必须在州内都是真的。
答案 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节点的实际数据结构取决于项目可能具有的元素数量。在您的示例中,仅使用四个字母。如果您的“字母”范围有限,则可以使用数组。否则你可能需要一种字典,这可能会使树在内存中占据相当大的比例。