Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.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#_Algorithm_Lcs_Needleman Wunsch - Fatal编程技术网

C# LCS算法:如何从一个表中找出有多少最长的公共子序列?

C# LCS算法:如何从一个表中找出有多少最长的公共子序列?,c#,algorithm,lcs,needleman-wunsch,C#,Algorithm,Lcs,Needleman Wunsch,我在C#中实现了最长的公共子序列问题。我需要检测两个字符串之间的所有公共最大子序列 为此,我创建了一个表,用于存储计算每个步骤的LCS序列 是否有机会确定找到了多少个最大子序列(使用表格) 根据这一点,我想选择一种方法来收集每个子序列。关键是,对于一个子序列,不需要递归,因此它将提供更好的性能。这对我的任务至关重要 下面是一段代码片段,其中实现了项目的基本功能: private static int[][] GetMatrixLCS(string x, string y)

我在C#中实现了最长的公共子序列问题。我需要检测两个字符串之间的所有公共最大子序列

为此,我创建了一个表,用于存储计算每个步骤的LCS序列

是否有机会确定找到了多少个最大子序列(使用表格)

根据这一点,我想选择一种方法来收集每个子序列。关键是,对于一个子序列,不需要递归,因此它将提供更好的性能。这对我的任务至关重要

下面是一段代码片段,其中实现了项目的基本功能:

    private static int[][] GetMatrixLCS(string x, string y)
        {
            var lenX = x.Length;
            var lenY = y.Length;
            matrixLCS = new int[lenX + 1][];
            for (var i = 0; i < matrixLCS.Length; i++)
            {
                matrixLCS[i] = new int[lenY + 1];
            }
            for (int i = 0; i <= lenX; i++)
            {
                for (int j = 0; j <= lenY; j++)
                {
                    if (i == 0 || j == 0)
                        matrixLCS[i][j] = 0;
                    else
                    if (x[i - 1] == y[j - 1])
                        matrixLCS[i][j] = matrixLCS[i - 1][j - 1] + 1;
                    else
                        matrixLCS[i][j] = Math.Max(matrixLCS[i - 1][j], matrixLCS[i][j - 1]);
                }
            }
            return matrixLCS;
        }

    static HashSet<string> FindAllLcs(string X, string Y, int lenX, int lenY)
        {
            var set = new HashSet<string>();
            if (lenX == 0 || lenY == 0)
                return emptySet;
            if (X[lenX - 1] == Y[lenY - 1])
            {
                var tempResult = FindAllLcs(X, Y, lenX - 1, lenY - 1);
                foreach (var temp in tempResult)
                    set.Add(temp + X[lenX - 1]);
                return set;
            }
            if (matrixLCS[lenX - 1][lenY] >= matrixLCS[lenX][lenY - 1])
                set = FindAllLcs(X, Y, lenX - 1, lenY);
            if (matrixLCS[lenX][lenY - 1] >= matrixLCS[lenX - 1][lenY])
                set.UnionWith(FindAllLcs(X, Y, lenX, lenY - 1));
            return set;
        }

我认为有可能对动态规划有一点不同的看法。也许它能起作用:

#包括
使用名称空间std;
结构TLSTValue{
内伦;
int-cnt;
};
无效更新(TLSTValue&v、常量TLSTValue&u){
如果(u.cnt==0){
返回;
}
如果(u.len>v.len){
v、 len=u.len;
v、 cnt=u.cnt;
}否则如果(u.len==v.len){
v、 cnt+=u.cnt;
}
}
int main(int/*argc*/,char**/*argv*/)
{
a、b串;
而(cin>>a>>b){
int n=a.size();
int m=b.size();
向量nxt(n,向量(m));
对于(int j=0;j=0;--i){
如果(a[i]==b[j]){
lst=i;
}
nxt[i][j]=lst;
}
}
向量f(n+1,向量(m+1,{0,0}));
f[0][0]={0,1};
TLSTValue ans={0,0};

对于(int i=0;i而言,最简单的方法是使用naive实现在迭代过程中通过矩阵记录所有匹配

我需要
allLCS()
进行测试,如果其他算法提供了有效的解决方案,那么它必须是所有可能的LCS之一

密码打开了

它是用Perl编写的,但很容易理解。遍历矩阵并在单元格中添加匹配项。最后,右下角单元格包含LCS的长度。这是一个简单的算法。现在,在每个匹配项处,将坐标作为数组[i,j]记录在哈希中,匹配计数作为键

#获取两个阵列的所有LCS
#按等级记录比赛
次级ALLCS{
我的($self,$X,$Y)=@;
my$m=标量@$X;
my$n=标量@$Y;
我的$ranks={};#例如'4'=>[[3,6],[4,5]]
我的$c=[];
我的($i,$j);
对于(0..$m){$c->[$\][0]=0;}
对于(0..$n){$c->[0][$\]=0;}
对于($i=1;$i[$j-1]){
$c->[$i][$j]=$c->[$i-1][$j-1]+1;
推送{$ranks->{$c->[$i][$j]},[$i-1,$j-1];
}
否则{
$c->[$i][$j]=
($c->[$i][$j-1]>$c->[$i-1][$j])
?$c->[$i][$j-1]
:$c->[$i-1][$j];
}
}
}
我的$max=标量键%$RANGS;
返回$self->\u all\u lcs($ranks,1,$max);
} 
最后,通过方法
\u all\u lcs()
连接记录的匹配项集合:

sub\u all\u lcs{
我的($self,$ranks,$rank,$max)=@;
我的$R=[[]];
而($rank{$rank}}){
if(标量@{$path}==0){
在温度下推送,[$hunk];
}
elsif(($path->[-1][0]<$hunk->[0])&($path->[-1][1]<$hunk->[1])){
按@temp,[@$path,$hunk];
}
}
}
@$R=@temp;
$rank++;
}
返回$R;
}
代码的灵感来自于该文件


Ronald I.Greenberg。

A有样本输入和预期输出会很好。@mjwills当然,我用示例编辑了这个问题
    public void SingleOutput()
    {
    var sequence = LCS.FindLCS("ABC", "AB");
    Assert.AreEqual(1, sequence.Length);
    Assert.AreEqual("AB", sequence[0]);
    }

    public void MultipleOutput() 
    { 
    var sequence = LCS.FindLCS("BCAB", "ABC"); 
    Assert.AreEqual(2, sequence.Length); 
    Assert.AreEqual("AB", sequence [0]);
    Assert.AreEqual("BC", sequence [1]);
    }
ABC and AB: length = 2, count = 1
BCAB and ABC: length = 2, count = 2
A and AAA: length = 1, count = 1
AAA and A: length = 1, count = 1
AAAB and ABBB: length = 2, count = 1
ABBB and AAAB: length = 2, count = 1