可能的字符串匹配的数据结构

时间:2013-08-02 20:21:14

标签: string algorithm data-structures

以下操作的最佳数据结构是什么:
数据结构存储单词列表
输入:一个字符串,我们将其命名为“pre”
输出:所有字符串列表中包含前缀作为其前缀(来自存储的单词列表),列表中的单词应按其优先级的降序排序。
如果在作为输出返回的字符串列表中使用特定字符串的优先级,则会增加该字符串的优先级 我将使用它进行单词预测,因此每次用户选择某个单词时(从返回单词列表中),它的优先级增加1. 我已经实现了一个trie 但它按字母顺序给出了输出(列表)我希望它按优先级排序。

4 个答案:

答案 0 :(得分:4)

您问题的最佳数据结构将是trie一个true将允许以空间为代价进行快速查找。

请点击此链接获取更多信息:link

答案 1 :(得分:1)

这可能不是最好的解决方案,但它可能会给你一些想法。

使用trie存储所有单词,并让您的节点包含优先级字段。

有一个列表数据结构,您的trie可以看到它与查询功能具有相同的范围。该列表将包含(单词,优先级)条目。

迭代输入字下面的树(所以'pre'下面的子树)并查找所有单词(可能是节点有一个布尔'单词'字段或其他东西)。当找到一个单词(单词== 1)时,您将(单词,优先级)添加到列表的末尾。

假设i是新条目的位置,然后将列表(i)与列表(i-1)进行比较。如果列表(i-1)的优先级小于列表(i),则切换其位置。继续这样做,直到第i-1项具有与新添加项相同或更高的优先级。

一旦trie-searching功能完成,您将有一个按降序排列的(字,优先级)条目列表。

我希望这是有道理的。

答案 2 :(得分:0)

如其他答案所示,您可以使用trie快速获取具有给定前缀的所有单词,然后根据其优先级对单词进行排序。忽略从trie获取匹配单词的访问时间,如果得到k匹配单词,则根据优先级排序需要O(k log k)时间。这非常接近理论上的最佳O(k)时间,您可能不想在实际应用中尝试改进它,特别是因为在排序后打印k个字实际上有运行时间{{ 1}}其中O(kl)是匹配单词的平均长度,而l的乘数通常可能大致与l的顺序相同。但是,如果您愿意将log k所使用的空间量乘以O(L_avg)是所有单词的平均长度,那么您可以获得按排序顺序访问单词并更新优先级+1下至L_avg,其中O(k + L log n)是获得优先级+1的所选字词的长度,L是您的总字数。

这个想法起初可能听起来有点疯狂,但请耐心等待,记忆真的只会乘以n,我会解释。我们的想法是,在您的trie的每个节点上,将所有具有相应前缀的单词及其优先级存储在自平衡二叉搜索树中(根据优先级排序)。您可以将单词作为索引表示为存储单词的数组,而不是整个单词,因此trie的每个节点的存储要求在具有相应前缀的单词数中是线性的。当一个单词获得优先级+1时,你必须通过trie并更新平衡二进制搜索树以获得该单词及其所有父节点的相应trie节点,这需要O(L_avg)时间。但是,为了响应查询以排序顺序获取单词的索引,您所要做的就是按预先顺序遍历二叉树,这需要O(L log n)时间。现在关于存储。长度为O(k)的单词存储在L二叉树中:用于单词的trie节点处的树,以及用于其所有L父节点的树。因此,如果在trie中的所有节点上为所有树添加总存储量,则通过计算树中每个单词出现次数的方式,总树存储量与所有单词的总长度成线性关系,即L-1。如果您可以处理存储的乘数,那么我相信这是处理查询和优先级更改的理论上最快的方法,如果您真的想要通过对查询结果进行排序来删除O(n L_avg)乘数。

答案 3 :(得分:0)

这是内存效率低下的解决方案。

参考:Trie example

在每个节点存储所有可能的有效后缀,这些后缀具有到目前为止遍历父项的前缀。同样为了快速检索,使用基于优先级的max heap来存储这些后缀。

例如,您的c ++ trie节点将如下所示(我尚未测试代码)

typedef pair<int, string> SUFFIX;
class Compare {
public:
    bool operator() (SUFFIX &d1, SUFFIX &d2) {
        return d1.first < d2.first;
    }
};
typedef priority_queue<SUFFIX, vector<SUFFIX>, Compare> max_heap;

struct TrieNode {
    char data; // char at current node
    max_heap word_suffixes; 
    bool is_complete;
};

/* Note: max_heap word_suffixes basically hold all strings without prefix so far. 
For example: You have dictionary of egg, eye at the starting node "e" your max
heap will have two entries "gg" and "ye" (with highest priority say "gg" 
as root of max heap) 
*/

现在时间复杂度

1)按照前缀&#34; pre&#34;遍历trie。 O(L)(L = len of pre)

2)在节点处弹出max heap中的每个字符串,这将为您提供按优先级排序的列表。 O(nlogn)(n =堆的大小)

3)在递增所用单词的优先级后重建堆。 O(nlogn)

注意:您也可以尝试将后缀存储为BST,优先级为关键。有序遍历将为您提供优先级排序的后缀列表(O(n))。通过从BST中删除后缀并重新添加新优先级(插入/搜索/删除将为O(高度)以实现平衡BST),可以增加使用的字的优先级。