有很多策略可以快速做到这一点。
理念一
获取您正在搜索的字符串,并从某个列开始复制每个可能的子字符串并继续整个字符串。然后将每一个存储在一个以它开头的字母为索引的数组中。(如果一个字母被使用两次,则存储较长的子串。
所以数组看起来像这样:
a - substr[0] = "astringthatmustbechecked"
b - substr[1] = "bechecked"
c - substr[2] = "checked"
d - substr[3] = "d"
e - substr[4] = "echecked"
f - substr[5] = null // since there is no 'f' in it
... and so forth
然后,对于字典中的每个单词,在其第一个字母表示的数组元素中进行搜索。这限制了必须搜索的内容的数量。另外,在字符串中的第一个 'r' 之前的任何位置,您都找不到以 'r' 开头的单词。如果字母根本不在其中,有些单词甚至不会进行搜索。
想法 2
通过注意字典中最长的单词来扩展这个想法,并从数组中那些比那个距离更长的字符串中删除字母。
所以你在数组中有这个:
a - substr[0] = "astringthatmustbechecked"
但如果列表中最长的单词是 5 个字母,则无需保留:
a - substr[0] = "astri"
如果这封信多次出现,您必须保留更多的信件。所以这个必须保留整个字符串,因为“e”总是显示不到 5 个字母。
e - substr[4] = "echecked"
在压缩字符串时,您可以通过使用以任何特定字母开头的最长单词来对此进行扩展。
想法 3
这与 1 和 2 无关。您可以使用它来代替。
您可以将字典转换为存储在链接数据结构中的一种正则表达式。也可以编写正则表达式然后应用它。
假设这些是字典中的单词:
arun
bob
bill
billy
body
jose
构建这种链接结构。(它实际上是一棵二叉树,我可以解释如何使用它。)
a -> r -> u -> n -> *
|
b -> i -> l -> l -> *
| | |
| o -> b -> * y -> *
| |
| d -> y -> *
|
j -> o -> s -> e -> *
箭头表示必须跟随另一个字母的字母。所以“r”必须在“a”之后,否则不能匹配。
向下的行表示一个选项。您有“a or b or j”可能的字母,然后在“b”之后有“i or o”可能的字母。
正则表达式看起来有点像: /(arun)|(b(ill(y+))|(o(b|dy)))|(jose)/ (尽管我可能漏掉了括号)。这给出了将其创建为正则表达式的要点。
构建此结构后,从第一列开始将其应用于字符串。尝试通过检查替代方案来运行匹配,如果匹配,则试探性地向前移动并尝试箭头后面的字母及其替代方案。如果您到达星号/星号,则匹配。如果您用完了包括回溯在内的备选方案,则移至下一列。
这是很多工作,但有时可以很方便。
旁注我以前通过编写一个程序来构建其中一个,该程序编写了直接运行算法的代码,而不是让代码查看二叉树数据结构。
将每组垂直条选项视为switch
针对特定字符列的语句,并且每个箭头都变成嵌套。如果只有一个选项,则不需要完整的switch
声明,只需if
.
那是一些快速的字符匹配,并且出于某种今天让我难以理解的原因非常方便。