Java “我们如何实现?”;子串匹配;在O(n)时间下?

Java “我们如何实现?”;子串匹配;在O(n)时间下?,java,string,algorithm,language-agnostic,Java,String,Algorithm,Language Agnostic,我有一项作业需要读取大量随机输入文件,例如: Adana Izmir Adnan Menderes Apt Addis Ababa Aden ADIYAMAN ALDAN Amman Marka Intl Airport Adak Island Adelaide Airport ANURADHAPURA Kodiak Apt DALLAS/ADDISON Ardabil ANDREWS AFB etc.. 如果我指定一个搜索词,程序应该找到子字符串出现的行。例如,如果搜索词为“uradha

我有一项作业需要读取大量随机输入文件,例如:

Adana 
Izmir Adnan Menderes Apt
Addis Ababa
Aden
ADIYAMAN
ALDAN
Amman Marka Intl Airport
Adak Island
Adelaide Airport
ANURADHAPURA
Kodiak Apt
DALLAS/ADDISON
Ardabil 
ANDREWS AFB
etc..
如果我指定一个搜索词,程序应该找到子字符串出现的行。例如,如果搜索词为“uradha”,则程序应显示
ANURADHAPURA
。如果搜索词为“机场”,则程序应显示安曼马尔卡国际机场、阿德莱德机场

作业规范中的一句话:“您需要在编写此应用程序时考虑到效率,就好像涉及到大量数据和处理……”

我可以使用一个循环轻松实现这个功能,但性能是O(n)。我曾考虑使用,但它似乎只有在子字符串从索引0开始时才起作用


我想知道有哪些解决方案的性能优于O(n)?

您可以查看或。它们具有良好的渐近性能,但我不知道有哪种算法不需要至少读取一次(几乎全部)输入和输出字符串,因此其性能优于O(n)(其中n是输入的大小)。

其中O(n)是最坏情况下的时间复杂度


顺便说一句,您应该将此链接添加到书签中:

我的直觉告诉您思考trie的方法是正确的,您可能想查看该链接上的trie页面的这一部分,了解更多想法。O(n)想法很不幸。

如果输入文本的内容几乎是静态的(或者不经常添加值,并且将值添加到输入源的末尾),那么搜索通常是可以尝试的(可能与trie相同)

1) 您将阅读所有文本(并在添加新元素后进行更新),并准备索引表(匹配发生的坐标(线或带位置的线)的符号映射)

2) 按前2个符号搜索索引表中的第一个坐标


3) 然后通过坐标继续在输入文本中搜索

Boyer Moore和一些算法,这些算法在其某些想法上使用变体,可以实现“O(n/m)”(其中n是草堆的长度,m是针的长度)在某些针上的最佳情况性能,但这取决于针上的不重复标准,对于任意大的m(例如,当m远大于字符集大小时),针上的不重复标准不可能满足,这使得即使是最好的情况也更像O(n/256),因此O(n)。在现实世界中,m往往很小,针头往往不是病理周期性的,BM及其近亲仍然可以表现得非常好


就我个人而言,我建议使用“双向”算法(在glibc实现中使用类似BM的扩展),因为它保证了O(n)界和恒定的工作空间。

所有行是否都像所示的那样短?@MichaelJ.Barber。基本上要求是模糊的,我只提供了一个示例文件:难道你不需要像量子计算机一样检查O(N)下N个项目的列表吗?@Pacerier:如果你有一个N个字符的输入字符串,你必须至少检查其中的每一个。如果没有量子计算机,你不能比O(n)更快。一个查询无法低于O(n),但是如果你有很多查询,那么你可以通过在O(n)时间内构建一个后缀树或后缀数组来获得很大的加速,然后用它来解决与查询长度成比例的每个查询。Heys sry我不明白你的意思,这是否意味着我需要一个所有可能的输入“a”到“zzzzz”(太大以至于无法实际使用)的映射,这就是所谓的“a”。它可以非常快,因为索引告诉您如何集中搜索。@Pacerier:是的,索引表会很大,甚至比输入源还要大,但它会提高搜索性能。@MichaelJ.Barber-heys很酷,但是假设我只有3个短输入
tiger
lion
,和
bear
,你的意思是我必须构建一个33行的表(t,I,g,e,r,ti,ig,ge,er,tig,ige,ger,tige,iger,tiger,l,o,n,li,io,on,lio,ion,lion,b,e,a,be,ea,ar,bea,ear,bear),因为我想知道这种方法的可扩展性有多大。运行测试文件()会得到286318行..对于短的已知子字符串,Rabin Karp可能也是一种可能性。
'aa' - 1, 15, 27... 
'as' - 1, 15, 17...
'ba' - 2, 3, 15...
...