有很多快速完成此操作的策略。
方法1
将要搜索的字符串复制,并针对从某列开始到整个字符串结束的每个可能的子字符串进行存储。然后将每个字符串存储在以它开头字母为索引的数组中。(如果字母出现两次,则存储较长的子字符串)。
因此,该数组看起来像这样:
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或b或j"的字母,然后在"b"之后是可能的"i或o"的字母。
正则表达式看起来像:/(arun)|(b(ill(y+))|(o(b|dy)))|(jose)/(虽然我可能会打错括号)。这大致说明了如何将其创建为正则表达式。
一旦你建立了这个结构,你就可以从第一列开始将其应用于你的字符串。尝试通过检查备选项来运行匹配,如果有一个匹配,则向前暂时移动并尝试箭头后面的字母及其备选项。如果你到达星号/星号,它就匹配了。如果你用完了备选项,包括回溯,你就移到下一列。
这是很多工作,但有时候会很方便。
附注:我之前写了一个程序,直接编写运行该算法的代码,而不是让代码查看二叉树数据结构。
想象每组垂直条选项都是针对特定字符列的
switch
语句,每个箭头都变成一个嵌套。如果只有一个选项,您不需要完整的
switch
语句,只需要一个
if
。
这是一些快速字符匹配技巧,出于某种原因,它今天很方便。