C# 如何在两个大字符串之间找到lcs长度
我在C# 如何在两个大字符串之间找到lcs长度,c#,.net,text,lcs,C#,.net,Text,Lcs,我在C 35;中编写了以下代码,用于获取由use给定的两个文本的最长公共子序列的长度,但它不适用于大字符串。你能帮帮我吗。我真的很困惑 public Form1() { InitializeComponent(); } public int lcs(char[] s1, char[] s2, int s1size, int s2size) { if (s1size == 0 || s2size == 0) { return 0; } el
C 35;
中编写了以下代码,用于获取由use给定的两个文本的最长公共子序列的长度,但它不适用于大字符串。你能帮帮我吗。我真的很困惑
public Form1()
{
InitializeComponent();
}
public int lcs(char[] s1, char[] s2, int s1size, int s2size)
{
if (s1size == 0 || s2size == 0)
{
return 0;
}
else
{
if (s1[s1size - 1] == s2[s2size - 1])
{
return (lcs(s1, s2, s1size - 1, s2size - 1) + 1);
}
else
{
int x = lcs(s1, s2, s1size, s2size - 1);
int y = lcs(s1, s2, s1size - 1, s2size);
if (x > y)
{
return x;
}
else
return y;
}
}
}
private void button1_Click(object sender, EventArgs e)
{
string st1 = textBox2.Text.Trim(' ');
string st2 = textBox3.Text.Trim(' ');
char[] a = st1.ToCharArray();
char[] b = st2.ToCharArray();
int s1 = a.Length;
int s2 = b.Length;
textBox1.Text = lcs(a, b, s1, s2).ToString();
}
这里使用的是递归方法。因此,它会导致程序出现您提到的性能问题 使用动态规划方法代替递归 这是C代码
公共静态无效LCS(char[]str1,char[]str2)
{
int[,]l=新int[str1.Length,str2.Length];
int lcs=-1;
string substr=string.Empty;
int end=-1;
for(int i=0;ilcs)
{
lcs=l[i,j];
end=i;
}
}
其他的
l[i,j]=0;
}
}
对于(int i=end-lcs+1;i,这里有一个如何在C#中找到最长公共子串的解决方案:
公共静态字符串GetLongestCommonSubstring(参数字符串[]字符串)
{
var commonSubstrings=new HashSet(字符串[0].GetSubstrings());
foreach(string中的string str.Skip(1))
{
commonSubstrings.IntersectWith(str.GetSubstrings());
if(commonSubstrings.Count==0)
返回字符串。空;
}
返回commonSubstrings.OrderByDescending(s=>s.Length).DefaultIfEmpty(string.Empty).First();
}
私有静态IEnumerable GetSubstring(此字符串str)
{
对于(int c=0;c 对于(int cc=1;c+cc只是为了好玩,这里有一个使用Queue
的示例:
string LongestCommonSubstring(params string[]strings)
{
返回LongestCommonSubstring(strings[0],新队列(strings.Skip(1));
}
字符串LongestCommonSubstring(字符串x,队列字符串)
{
if(!strings.TryDequeue(out变量y))
{
返回x;
}
var输出=string.Empty;
对于(int i=0;i-1;j--)
{
字符串公共=x.子字符串(i,j);
如果(y.IndexOf(common)>-1&&common.Length>output.Length)output=common;
}
}
返回LongestCommonSubstring(输出,字符串);
}
它仍然使用递归,但是它是一个很好的例子,代码< >队列< /> > .< /p> < p>我重构了C++中的C++代码,在C语言中创建滚动哈希方法,这将发现O(n*log(n)^ 2)和O(n)空间中的子串。
使用系统;
使用System.Collections.Generic;
公共类滚球
{
私有类RollinghashPower
{
//_mod=多项式散列的素数模
//任何超过十亿的素数都应该足够了
内部常数int _mod=(int)1e9+123;
//_hashBase=base(散列点)
//这应该是一个大于所用字符数的素数
//在我的用例中,我只对ASCII(256)字符感兴趣
//对于使用非拉丁字符的语言中的字符串,这应该大得多
内部常量long _hashBase=257;
//_pow1=基模模模的幂
内部只读列表_pow1=新列表{1};
//_pow2=基模2^64的幂
内部只读列表_pow2=新列表{1L};
内部空隙长度(内部长度)
{
如果(_pow1.容量<长度)
{
_功率1.容量=_功率2.容量=长度;
}
对于(int currentIndx=_pow1.Count-1;currentIndx=0
?b.子串(位置,低)
:string.Empty;
}
}
字符串有多大?为什么c
tag?使用递归函数会导致出现此问题,朋友,是否可以不使用递归函数?最短的方法是找到单词的所有迭代,并将contains string函数与第二个字符串一起使用。这将给出答案,然后您可以可以从中获得长度。问题是tagg
public static void LCS(char[] str1, char[] str2)
{
int[,] l = new int[str1.Length, str2.Length];
int lcs = -1;
string substr = string.Empty;
int end = -1;
for (int i = 0; i < str1.Length; i++)
{
for (int j = 0; j < str2.Length; j++)
{
if (str1[i] == str2[j])
{
if (i == 0 || j == 0)
{
l[i, j] = 1;
}
else
l[i, j] = l[i - 1, j - 1] + 1;
if (l[i, j] > lcs)
{
lcs = l[i, j];
end = i;
}
}
else
l[i, j] = 0;
}
}
for (int i = end - lcs + 1; i <= end; i++)
{
substr += str1[i];
}
Console.WriteLine("Longest Common SubString Length = {0}, Longest Common Substring = {1}", lcs, substr);
}
public static string GetLongestCommonSubstring(params string[] strings)
{
var commonSubstrings = new HashSet<string>(strings[0].GetSubstrings());
foreach (string str in strings.Skip(1))
{
commonSubstrings.IntersectWith(str.GetSubstrings());
if (commonSubstrings.Count == 0)
return string.Empty;
}
return commonSubstrings.OrderByDescending(s => s.Length).DefaultIfEmpty(string.Empty).First();
}
private static IEnumerable<string> GetSubstrings(this string str)
{
for (int c = 0; c < str.Length - 1; c++)
{
for (int cc = 1; c + cc <= str.Length; cc++)
{
yield return str.Substring(c, cc);
}
}
}