Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在两个大字符串之间找到lcs长度_C#_.net_Text_Lcs - Fatal编程技术网

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);
        }
    }
}