最短前缀匹配算法?

时间:2012-02-18 04:48:25

标签: algorithm

给定String p和字符串列表找到最短的字符串,其中p是前缀。

我知道蛮力方法,但最佳方法是什么?

e.g。

p = "foo bar"
list = {"foo bar 1",
        "foo bar foo bar",
        "bar foo foo foo bar bar"};

应该返回“foo bar 1”

3 个答案:

答案 0 :(得分:2)

如果你已经拥有一个搜索空间(在你的情况下,一个相对恒定的list),那么生成一个或一些其他合适的结构将有助于搜索很多。从维基百科开始,它详细解释了这一点,以帮助您入门:

这是上面文章中使用单词的图像(很容易扩展到使用任何类型的字符串甚至非字符串):

A trie for keys "A", "to", "tea", "ted", "ten", "i", "in", and "inn".

本文提供了与其他合适结构的性能比较,这对您的情况很有帮助。

请注意,如果列表变化足够充分,那么此方法的回报可能会减少,或者与蛮力相比甚至可能会有更差的表现。

答案 1 :(得分:0)

您可能已经考虑过的简单方法基本上只是在每次传递后检查字符串的长度。

使用psuedo-C#:

int length = 0, index;
string p = "foo bar"
string[] list = new string[]{"foo bar 1",
    "foo bar foo bar",
    "bar foo foo foo bar bar"};
for(int i = 0; i < list.Length; i++) {
    if(list[i].Contains(p)) {
        if(list[i].Length < length) {
            index = i;
            length = list[i].Length;
        }
    }
}
MessageBox.Show("The shortest one is " + list[index]);

答案 2 :(得分:0)

如果你需要为 p运行它,那么直截了当的方法:

  1. 查找以lst
  2. 开头的p中的所有字符串
  3. 找出其中最短的
  4. 它已经是最佳的O(n)及时,O(1)在空间中,在Python中:

    shortest_with_prefix = min((s for s in lst if s.startswith(p)), key=len)
    

    如果有多个p,但lst相同,那么您可以将lst预处理到前缀树(Trie)中,以便更快地进行多次搜索的Python:

    from pytrie import StringTrie # pip install pytrie
    
    trie = StringTrie.fromkeys(lst)
    shortest_with_prefix = min(trie.iterkeys(prefix=p), key=len)