String 两个字符串序列中最长的公共子字符串

String 两个字符串序列中最长的公共子字符串,string,algorithm,data-structures,String,Algorithm,Data Structures,刚刚学习了最长的通用子串算法,我对这个问题的一个特殊变体感到好奇。其描述如下-: 给定两个非空字符串序列,X=(x1,x2,x3,…,X(n))和Y=(y1,y2,y3,…,Y(m)),其中X(i)和Y(i)是字符串,在X中找到最长的字符串,它是所有字符串的子字符串 我有一个函数substring(x,y),它返回布尔值,描述x是否是y中的子字符串。显然,我必须将Y中的所有字符串连接起来,形成一个大字符串,例如,用B表示。我想到了以下方法-: Naive:首先将X中的所有字符串连接起来,形成一

刚刚学习了最长的通用子串算法,我对这个问题的一个特殊变体感到好奇。其描述如下-:

给定两个非空字符串序列,X=(x1,x2,x3,…,X(n))和Y=(y1,y2,y3,…,Y(m)),其中X(i)和Y(i)是字符串,在X中找到最长的字符串,它是所有字符串的子字符串

我有一个函数
substring(x,y)
,它返回布尔值,描述x是否是y中的子字符串。显然,我必须将Y中的所有字符串连接起来,形成一个大字符串,例如,用B表示。我想到了以下方法-:

  • Naive:首先将X中的所有字符串连接起来,形成一个字符串a(n)。应用子字符串(A(n),B)-这包括在字符串A(n)中向后迭代。如果为true,则该算法在此结束并返回(n)-或包含在所述子字符串中的任何部分。如果没有,则继续应用(A(n-1)、B)等。如果X中不存在这样的字符串,则返回空字符串
显然,根据实现情况,此方法将占用相当多的运行时间。假设我使用迭代方法,在每次迭代中,我必须在该级别/索引上反向迭代字符串,然后应用substring()。它至少需要两个循环,并且
O(大小(B)*maxlength(x1,x2,…)
最坏情况时间,或者更多,具体取决于子字符串()(如果错误,请更正我)

我想到了第二种基于后缀树/数组的方法

  • 广义后缀树:我在
    O(maxlength(y1,y2,…)
    (?)中使用Ukkonen算法构建序列Y的GST。我对后缀树的知识缺乏。我相信后缀树方法将大大减少运行时间(以空间为代价)用于查找子字符串,但我不知道如何实现该操作
如果有更好的方法,我很想知道

编辑:如果我似乎放弃了这个话题,我深表歉意

如果我使用的不是GST,而是一些标准的数据结构,如堆栈、队列、集合、堆、优先级队列等,该怎么办?序列X必须先排序,自然是最大的字符串。如果我将其存储在字符串数组中,我将不得不使用排序算法,如mergesort/quicksort。目标是获得最有效的运行时间e尽可能地

我能不能将X存储在一个结构中,该结构在构建自身时自动对其元素进行排序?最大堆呢


后缀树似乎是以这种方式查找子字符串的最佳方法。我是否可以使用其他数据结构?

首先,将数组X中最长字符串的顺序改为较短。这样,X中的第一个字符串即所有Y字符串的子字符串就是解决方案


多处理器算法将是解决快速使用所有Y字符串测试每个X字符串的问题的最佳方法。

以下是我对您的问题的解决方案的想法;我不确定所有问题,因此如果您认为值得努力,欢迎评论以改进它

首先计算Y中所有字符串的所有公共子字符串。首先取两个字符串,并构建一个包含所有公共子字符串的树。然后,对于Y中的每个其他字符串,从映射中删除此字符串中未出现的每个子字符串。复杂性与Y中字符串的数量成线性关系,但我无法计算出可能包含多少个元素在树中,因此我无法估计最终的复杂性

然后找到X中最长的字符串,它是树中1的子字符串


为了使树尽可能小,必须做一些改进,例如只保留不属于其他字符串的子字符串。

为集合Y中的字符串数写入| Y |,为其总长度写入len(Y):

  • 将Y中的字符串处理为a(例如,使用)。需要时间O(len(Y)),假设字母表大小不变

  • 根据由该节点标识的字符串是否属于Y中的所有字符串,标记后缀树中的每个节点。花费时间O(| Y | len(Y))

  • 对于X中的每个字符串,在后缀树中查找它,并查看节点是否标记为属于Y中的所有字符串。输出最长的标记字符串。需要时间O(len(X))


  • 总时间:O(|Y | len(Y))+O(len(X))。

    您想要的字符串是Y中所有字符串的子字符串。但B是所有字符串的并集(不是交集)。因此,您将找到Y中至少1个字符串的子字符串。我是否遗漏了某些内容?m字符串重叠的子字符串不一定是其中一个m字符串的子字符串。因此,以下语句为false:“显然,我必须将Y中的所有字符串连接起来,形成一个大字符串,比如说,用B表示。”Y是一个字符串序列。我不应该寻找所有字符串的并集/连接吗?这就是我读“Y中的所有字符串”时的想法"。我可能把这搞砸了。你能用一个例子解释一下吗?这种方法会不会花很长时间,因为我们必须一次取两个字符串?@TheRedBlackTree你一次只取前两个字符串;然后你一次只取一个字符串,并从树中删除字符串中不存在的所有子字符串。我认为整个过程都很简单g可能会被故意的数据结构加速,我只是在这里给出我的想法。这似乎是一个非常可行的方法。我想知道是否有可能降低复杂性,但我想如果我要使用后缀树,这是处理它的最好方法。我喜欢多处理器方法-肯定会提供一些动力。我正在寻找我不知道你想用什么语言,但是在c语言中你有库mpich2,在R语言中有包foreach。