如何在字符串中找到连续字符的交叉点?

时间:2014-07-21 23:17:54

标签: c# string

假设我有以下字符串:

  1. blahFOOblahblah
  2. blahblahBARblah
  3. FIZZblahblahblah
  4. 现在,我想查询其中的每一个,以发现它们中的哪一个包含以下任何子字符串:

    FIZZbuzz

    显然,这个字符串分享了" FIZZ"与#3相同。

    我已经看过this post,因为它只关注字符(以任何顺序)而不是子字符串,因此它并没有完全实现我的目标。

1 个答案:

答案 0 :(得分:4)

您是否在寻找longest common substring之类的内容?

有快速但非常复杂的算法可以通过构建和使用suffix trees来解决任务。对于常量字母表,它们有O(n)时间,在最坏的情况下,O(n log(n))时间为n,其中public int LongestCommonSubstring(string str1, string str2, out string sequence) { sequence = string.Empty; if (String.IsNullOrEmpty(str1) || String.IsNullOrEmpty(str2)) return 0; int[,] num = new int[str1.Length, str2.Length]; int maxlen = 0; int lastSubsBegin = 0; StringBuilder sequenceBuilder = new StringBuilder(); for (int i = 0; i < str1.Length; i++) { for (int j = 0; j < str2.Length; j++) { if (str1[i] != str2[j]) num[i, j] = 0; else { if ((i == 0) || (j == 0)) num[i, j] = 1; else num[i, j] = 1 + num[i - 1, j - 1]; if (num[i, j] > maxlen) { maxlen = num[i, j]; int thisSubsBegin = i - num[i, j] + 1; if (lastSubsBegin == thisSubsBegin) {//if the current LCS is the same as the last time this block ran sequenceBuilder.Append(str1[i]); } else //this block resets the string builder if a different LCS is found { lastSubsBegin = thisSubsBegin; sequenceBuilder.Length = 0; //clear it sequenceBuilder.Append(str1.Substring(lastSubsBegin, (i + 1) - lastSubsBegin)); } } } } } sequence = sequenceBuilder.ToString(); return maxlen; } 是字符串的最大长度。

下面是一个可能的C#实现(来自http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Longest_common_substring)。它不是最优的,但在我们的情况下可能就足够了。

{{1}}