String 如何找到字符串的句点
我从用户那里获取一个输入,它是一个带有特定子字符串的字符串,该子字符串在整个字符串中重复。我需要输出子字符串或其长度(即周期) 说String 如何找到字符串的句点,string,algorithm,substring,String,Algorithm,Substring,我从用户那里获取一个输入,它是一个带有特定子字符串的字符串,该子字符串在整个字符串中重复。我需要输出子字符串或其长度(即周期) 说 我可以从一个字符开始,检查它是否与下一个字符相同,如果不是,我可以用两个字符,然后用三个字符,依此类推。这将是一个O(N^2)算法。我想知道是否有更优雅的解决方案。如果输入字符串中的每个字符都是重复子字符串的一部分,那么您所要做的就是存储第一个字符,并将其与字符串的其余字符逐个进行比较。如果找到匹配项,则字符串直到匹配一个是您的重复字符串。您可以在线性时间内为整个字
我可以从一个字符开始,检查它是否与下一个字符相同,如果不是,我可以用两个字符,然后用三个字符,依此类推。这将是一个O(N^2)算法。我想知道是否有更优雅的解决方案。如果输入字符串中的每个字符都是重复子字符串的一部分,那么您所要做的就是存储第一个字符,并将其与字符串的其余字符逐个进行比较。如果找到匹配项,则字符串直到匹配一个是您的重复字符串。您可以在线性时间内为整个字符串构建后缀树(后缀树很容易在线查找),然后递归计算并存储后缀树的每个内部节点v下的后缀树叶数(后缀前缀的出现次数)N(v)。还递归地计算并存储树的每个节点上每个后缀前缀L(v)的长度。然后,在树中的内部节点v处,在v处编码的后缀前缀是一个重复的子序列,如果N(v)等于字符串的总长度除以L(v),则会生成字符串。让我假设字符串
N
的长度至少是句点p
的两倍
算法
m
=1,让S
代表整个字符串m
=m*2
- 查找子字符串S[:m]的下一个匹配项
- 让
作为下一个事件的开始k
- 检查S[:k]是否为周期
- 如果没有,请转到2
CDCDFBFCDCDFDFCDCDFBFCDCDFDFCDC
对于2的每一次幂m
,我们可以找到前2^m
字符的重复。然后我们将这个序列扩展到它的第二次出现。让我们从2^1 soCD
开始
CDCDFBFCDCDFDFCDCDFBFCDCDFDFCDC
CDCD CDCD CDCD CDCD CD
CDCDFBFCDCDFDFCDCDFBFCDCDFDFCDC
CDCD CDCD
我们不扩展CD
,因为下一个事件就在那之后。但是CD
不是我们正在寻找的子字符串,所以让我们来看看下一个幂:2^2=4
和子字符串CDCD
CDCDFBFCDCDFDFCDCDFBFCDCDFDFCDC
CDCD CDCD CDCD CDCD CD
CDCDFBFCDCDFDFCDCDFBFCDCDFDFCDC
CDCD CDCD
现在让我们将字符串扩展到第一个重复。我们得到
CDCDFBF
我们检查这是否是周期性的。事实并非如此,我们要走得更远。我们尝试2^3=8,所以cdcdcdfbfc
CDCDFBFCDCDFDFCDCDFBFCDCDFDFCDC
CDCDFBFC CDCDFBFC
我们试图扩展,我们得到了
CDCDFBFCDCDFDF
这确实是我们的时代
我希望这能在O(nlogn)中使用类似于KMP的算法来检查给定字符串出现的位置。请注意,此处仍应计算一些边缘情况
直觉上这应该是可行的,但我的直觉在这个问题上已经失败了一次,所以如果我错了,请纠正我。我会设法找出一个证据
这是一个很好的问题。通过归纳计算字符串的每个前缀的周期,可以在线性时间和恒定的额外空间中实现这一点。我记不起细节(有几件事情需要纠正),但你可以在中找到它们。我也一直在寻找这个问题的时空最优解决方案。基本上看起来是这样的,但我想解释一下它到底是关于什么的,以及一些进一步的发现 首先,我提出的这个问题提出了一个看似有希望但不正确的解决方案,并说明了其不正确的原因: 一般来说,“查找周期”问题相当于“查找自身内的模式”(在某种意义上是“
strstr(x+1,x)
”),但没有超过其结束的约束匹配。这意味着您可以通过采用任何从左到右的字符串匹配算法,并将其应用于自身,将到达草堆/文本末尾的部分匹配视为匹配,来找到周期,并且时间和空间要求与您使用的任何字符串匹配算法相同
tmyklebu的回答中引用的方法实质上也是将这一原则应用于。另一个时空最优解决方案应该可以使用
不幸的是,这个相当著名且简单的算法不是一个解决方案,因为它不是从左到右的。特别是,左因子失配后的推进取决于右因子已经匹配,并且不可能与右因子模右因子的周期未对齐的另一个匹配。当在模式本身中搜索并忽略结束后的任何内容时,我们无法确定下一个右因子匹配的发生时间(部分或全部右因子可能已经移动到模式结束后),因此无法进行保留线性时间的移动
当然,如果工作空间可用,可以使用许多其他算法。KMP是具有O(n)空间的线性时间,可以将其调整为仅具有对数空间的合理有效时间。为什么S2子串不是AB?现在我对S3感到困惑。ABC不重复,或者这也是一个打字错误?对不起,我太挑剔了,我只是想弄清楚你到底想要输出什么。输入字符串中的每个字符都是重复子字符串的一部分。不管字符串的长度是多少@csmckelveyFor字符串“ababababxxxxabababababxxxx”tortoise and hare为您提供句点2,而实际句点为10。您能否给出一个代码示例,说明这如何适用于两个输入?伙计。阅读我问题中示例下面的一段文字:|哦,我没看到。但既然您说它必须包含一个循环,那么该方法的复杂性将是O(N),因为在最坏的情况下,您只是将第一个字符与整个字符串进行比较@csmckelvey伪代码如下:
charfirst=input[0];字符串重复字符串=第一个;int i=1;char nextChar=输入[i];while(first!=nextChar){repeatingString+=nextChar;i++;nextChar=input