挑战在于编写代码以解决以下问题。
给定两个字符串A和B,您的代码应输出具有以下属性的A子字符串的开始和结束索引。
- A的子字符串也应该与B的某些子字符串匹配。
- 不再有满足第一个属性的A子字符串。
例如:
A = xxxappleyyyyyyy
B = zapplezzz
apple
带有索引4 8
(索引从1开始)的子字符串将是有效的输出。
功能性
您可以选择输入是本地目录中文件中的标准输入还是您自己的选择。文件格式将只是两个字符串,用换行符分隔。答案应该是完整的程序,而不仅仅是功能。
我最终想在从http://hgdownload.cse.ucsc.edu/goldenPath/hg38/chromosomes/的字符串中提取的两个子字符串上测试您的代码。
得分
这是带有扭曲的代码高尔夫球。您的代码必须及时运行O(n)
,其中n
表示输入的总长度。
语言和图书馆
您可以使用具有免费编译器/解释器/等的任何语言。对于Linux。您应该只使用不是为解决此任务而设计的标准开源库。如有争议,我将其视为您的语言所标配的任何库,或者可以从默认存储库安装在默认ubuntu计算机中的任何库。
有用的信息
在线性时间内至少有两种方法可以解决此问题。一种是首先计算后缀树,第二种是首先计算后缀数组和LCP数组。
- 这是线性时间后缀树构造的完整(也许是过度)详细说明(不幸的是,有些数字被弄乱了)。关于https://stackoverflow.com/questions/9452701/ukkonens-suffix-tree-algorithm-in-plain-english的线性时间后缀树构造,还有一个非常好的SO答案。它还包括到源代码的链接。可以在这里找到另一个详细的说明,这一次提供了使用C的完整解决方案。
- http://www.cs.cmu.edu/~guyb/realworld/papersS04/KaSa03.pdf的第2节给出了线性时间后缀数组构造算法,附录A具有C ++源代码。该答案告诉您如何计算最长的公共子字符串https://cs.stackexchange.com/questions/9555/computing-the-longest-common-substring-of-two-strings-using-suffix-arrays。https://courses.csail.mit.edu/6.851/spring12/scribe/lec16.pdf的第5节,其中也有相关的视频讲座https://courses.csail.mit.edu/6.851/spring12/lectures/L16 .html还解释了从1:16:00开始的相同算法。
@Lembik对不起,但是这些是非常复杂的算法,而且要遍历100多行代码并不是很有趣。
—
FUZxxl 2015年
您在“有用的信息”下提供的第二个链接上的文章说:“构造[后缀树]需要O(N ^ 2)时间”
—
KSFT 2015年
@Lembik您应该提出一个问题[最快的代码],在这种情况下,采用大哦表示法的最坏情况下的最佳程序将获胜。然后,您至少会得到一些答案,即使有人可以在O(n)中解决问题,他们也会赢。
—
mbomb007'7
这必须是每个有效答案中删除的答案最多的问题……
—
FlipTack
O(n) time
您确定有可能吗?