我知道,也许这个问题很愚蠢但是我被困住了,我需要真正的帮助。我需要在我的项目中使用算法,它可以找到所有单词从另一个单词开始并返回所有单词的尾部。例如:
查找所有以dad
在词典中我们有:
dada, dadaism, daddled, daddling
结果:
a, aism, dled, dling
我有所有单词的字典,所以我需要的只是算法。有人建议我使用patricia算法,但我找不到任何C#样本。我的字典很大,所以我需要找到非常快的算法。
更多信息:
答案 0 :(得分:3)
这听起来像是Trie / DAWG(有向非循环字图)的完美用法。据我所知,帕特里夏树是一种类似于特里的变体。有a nice article about Tries and an implementation here。
答案 1 :(得分:3)
如何完成这项工作取决于词典的排列方式。如果它是一个排序的单词列表,那么您可以使用二进制搜索来查找以“dad”开头的第一个单词,然后循环使用StartsWith
和Substring
的单词。那就是:
List<string> Words = LoadWords(); // however you load them
Words.Sort();
// Now, search for "dad" (or whatever)
string prefix = "dad";
int index = Words.BinarySearch(prefix);
// If the returned index is negative, the word wasn't found.
// The index is the one's compliment of the the place where it would be in the list.
if (index < 0)
{
index = ~index;
}
for (int i = index; i < Count && Words[i].StartsWith(prefix))
{
Console.WriteLine(Words[i].Substring(prefix.Length));
}
这应该非常快。排序是加载后的一次性成本。如果按排序顺序存储字典,则可以完全消除它。二进制搜索是O(log n),其中n是字典中的单词数。
如果你的词典是无序的,那么你将不得不翻阅所有的词,这将花费很多时间。
您的词典还有其他组织,这将使它占用更少的空间,并且可能更快。这些更复杂,并且比创建排序列表花费更多时间。
答案 2 :(得分:1)
我所知道的最着名的是"knuth morris pratt string matching algorithm"。
如果你看一下链接,还有其他一些像Boyer-Moore字符串搜索算法,......
这些是通用算法,但如果您对特殊情况感兴趣,比如开始,...在大多数情况下,语言都有这种情况,例如在C#中你可以使用StartsWith
,EndsWith
,没有需要再次实施它们。
答案 3 :(得分:1)
对于非常小的词典,for循环可能非常快。但是如果你有来自成千上万个单词的匹配集,那将非常慢。假设您的字典已排序(如果没有排序),您可以使用BinarySearch函数找到第一个和最后一个范围项,然后使用for循环来创建结果。
为了更实际,我有一个(排序的)字典,包含354984个单词,包括从爸爸开始的35个单词:爸爸,爸爸,达达,达达主义,达达主义,达达主义者,达达主义者,达达主义者,达达主义者,爸爸,爸爸,爸爸,爸爸,爸爸,爸爸,爸爸,爸爸,爸爸,爸爸,爸爸,爸爸,爸爸,爸爸,爸爸,dade,dadenhudd,dading,dado,dadoed,爸爸,dadoing,爸爸,爸爸,爸爸和爸爸。如果我遵循Jim的方法,我将不得不执行35“StartsWith”,这是好的。在“sat”前缀的情况下,我有228个单词,如果是“cat”前缀,我有692个单词。对于我的字典大小,我需要总共40个字符串比较(最坏的情况)来找到第一个和最后一个项目。
如果您愿意使用任何trie实现,请确保如果您的字典包含第1或实时记录,则至少支持数字和短划线。
答案 4 :(得分:0)
您可以使用TRIE。您可以找到全面的实施和教程here。
基本上,在这个结构中,你将最终从Root到'd'然后到'a'然后再到'd'。你会想到所有以'dad'开头的单词。现在将其视为根节点,您所要做的就是探索下面的所有可能路径,然后进行算法
答案 5 :(得分:0)
如果您需要简单的东西,可以试试这个:
string[] dict = new string[] { "dada", "dadaism", "daddled", "daddling" };
string prefix = "dad";
var words = from d in dict
where d.StartsWith(prefix)
select d.Substring(prefix.Length);