c# - 最长公共(public)子序列

标签 c# string matrix backtracking lcs

您好,这是我在 c# 中为 2 个字符串创建最长公共(public)子序列的代码。我在回溯方面需要帮助。我需要找出子序列:GTCGT

String str1 = "GTCGTTCG";
String str2 = "ACCGGTCGAGTG";

int[,] l = new int[str1.Length, str2.Length]; // String 1 length and string 2      length storing it in a 2-dimensional array
int lcs = -1;
string substr = string.Empty;
int end = -1;

for (int i = 0; i <str1.Length ; i++) // Looping based on string1 length 
{                
  for (int j = 0; j < str2.Length; j++) // Looping based on string2 Length
  {                  
    if (str1[i] == str2[j]) // if match found 
    {
      if (i == 0 || j == 0)  // i is first element or j is first elemnt then array [i,j] = 1
      {
        l[i, j] = 1;
      }
      else
      {   
        l[i, j] = l[i - 1, j - 1] + 1; // fetch the upper value and increment by 1 
      }

      if (l[i, j] > lcs)
      {
        lcs = l[i, j]; // store lcs value - how many time lcs is found 
        end = i; // index on longest continuous string
      }

    }
    else // if match not found store zero initialze the array value by zero
    {
      l[i, j] = 0;
    }
}

最佳答案

您的函数需要返回一个字符串集合。可能存在多个相同长度的最长公共(public)子序列。

public List<string> LCS(string firstString, string secondString)
{
    // to create the lcs table easier which has first row and column empty.
    string firstStringTemp = " " + firstString;
    string secondStringTemp = " " + secondString;

    // create the table
    List<string>[,] temp = new List<string>[firstStringTemp.Length, secondStringTemp.Length];

    // loop over all items in the table.
    for (int i = 0; i < firstStringTemp.Length; i++)
    {
        for (int j = 0; j < secondStringTemp.Length; j++)
        {

            temp[i, j] = new List<string>();
            if (i == 0 || j == 0) continue;
            if (firstStringTemp[i] == secondStringTemp[j])
            {
                var a = firstStringTemp[i].ToString();
                if (temp[i - 1, j - 1].Count == 0)
                {
                    temp[i, j].Add(a);
                }
                else
                {
                    foreach (string s in temp[i - 1, j - 1])
                    {
                        temp[i, j].Add(s + a);
                    }
                }
            }
            else
            {
                List<string> b = temp[i - 1, j].Concat(temp[i, j - 1]).Distinct().ToList();
                if (b.Count == 0) continue;
                int max = b.Max(p => p.Length);
                b = b.Where(p => p.Length == max).ToList();
                temp[i, j] = b;
            }
        }
    }
    return temp[firstStringTemp.Length - 1, secondStringTemp.Length - 1];
}

您需要在表的每个条目中设置一个集合。因此,您仍然可以在表格的每个单元格中保留具有相同长度的不同字符串。

关于c# - 最长公共(public)子序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19984276/

相关文章:

c# - 在 LINQ to SQL 中使用 contains()

c# - 递增字符串中的数字 (C#)

regex - 如何在 Perl 中使用正则表达式拆分字符串?

python - 如何打印二维矩阵并添加标签,同时保持所有内容居中 (Python)

c# - 字符串在c#中动态分割

c# - 根据 API 使用情况动态创建编译器错误?

c# - NancyFX 中的静态内容与 ASP.Net Core

string - 用于测量两个字符串中出现的大小 >=2 的子序列数量的指标

r - 分散NA值的矩阵乘法

java - 如何对 nxn 矩阵(最多 n=2^i)测试 1000 组数据,每组数据 20 次?