算法按前缀分区字符串

时间:2018-01-10 01:56:57

标签: string algorithm go prefix

给定字符串L(已排序)和正整数N(N <= len(L))的列表,如何通过长度为N的公共前缀有效地将L分割为不超过N组

示例:定义数据结构和功能如下:

type PrefixGroup struct {
    Prefix string 
    Count  int
}
func partition(L []string, N int, prefix string) []PrefixGroup

当使用

调用时,列表L可能包含数千个字符串
partition(L, 8, "")

输出可能是:

[
    {"Prefix":"13", "Count":1000},
    {"Prefix":"180": "Count": 10},
    {"Prefix":"X": "Count": 2},
    ... ...
]

表示在L中,有1000个字符串以“13”开头,10个以“180”开头,2个以“X”开头。请注意,前缀的长度已修复。该算法的关键要求是使用公共前缀对字符串进行分区,以使组的数量尽可能接近但不超过N.

根据上面的结果,我可以调用partition(L, 8, "13")来进一步深入研究以“13”开头的L子集:

[
    {"Prefix":"131", "Count": 50},
    {"Prefix":"135": "Count": 100},
    {"Prefix":"136": "Count": 500},
    ... ...
]

这是一个家庭作业问题。我需要为手头的项目编写这样的算法。我可以把它写成“蛮力” - 只是想知道是否有任何经典/众所周知的数据结构和/或算法来实现经过验证的时间/空间效率。

我考虑过trie,但想知道它是否会消耗太多内存......

2 个答案:

答案 0 :(得分:1)

嗯,有一些算法,但前缀树是可行的。

  

前缀树或trie(通常发音为“try”)是一个树,其节点不保持键,而是保存部分键。例如,如果您有一个存储字符串的前缀树,那么每个节点都将是一个字符串的字符。如果您有一个存储数组的前缀树,则每个节点都是该数组的元素。元素从根开始排序。因此,如果您的前缀树中包含单词“hello”,则根节点将具有子节点“h”,而“h”节点将具有子节点“e”,并且“e”节点将具有有一个子节点“l”,等等。一个键的最深节点会有一些布尔标志,表明它是某个键的终端节点。 (这很重要,因为密钥的最后一个节点并不总是叶节点...考虑一个前缀树,其中包含“dog”和“doggy”)。前缀树适用于查找具有特定前缀的密钥。

答案 1 :(得分:1)

您需要使用Radix trie。 您可以阅读the difference between a trie and a Radix trie