最长的Common Substring:递归解决方案?

问题描述 投票:3回答:4

常见的子串算法:

LCS(x,y) = 1+ LCS(x[0...xi-1],y[0...yj-1] if x[xi]==y[yj]
           else 0

现在动态编程解决方案已经很好理解了。但是我无法弄清楚递归解决方案。如果有多个子串,则上述算法似乎失败。

例如:

x = "LABFQDB" and y = "LABDB"

应用上述算法

1+ (x=  "LABFQD" and y = "LABD")
1+ (x=  "LABFQ" and y = "LAB")
return 0 since 'Q'!='B'

返回的值是2,我应该是3?

有人可以指定递归解决方案吗?

string algorithm recursion dynamic-programming
4个回答
-2
投票

您不理解该算法,因为它不是最长公共子串的算法...

正确的公式是:

LCS(x,y) = 1+ LCS(x[0...xi-1],y[0...yj-1]) if x[xi]==y[yj]
           else max(LCS(x[0...xi],y[0...yj-1]), LCS(x[0...xi-1],y[0...yj]))

0
投票
long max_sub(int i, int j)
{

    if(i<0 or j<0)
        return 0;

    if(s[i]==p[j])
    {
        if(dp[i][j]==-1)
          dp[i][j]=1+max_sub(i-1,j-1);
    }
    else
    {
        dp[i][j] = 0;
    }
    if(i-1>=0 and dp[i-1][j]==-1)
        max_sub(i-1, j);
    if(j-1>=0 and dp[i][j-1]==-1)
        max_sub(i, j-1);
    return dp[i][j];
}

你的代码的问题似乎是你没有尝试所有n ^ 2的可能性。


0
投票

包algo.dynamic;

public class LongestCommonSubstring {

public static void main(String[] args) {
    String a = "LABFQDB";
    String b = "LABDB";
    int maxLcs = lcs(a.toCharArray(), b.toCharArray(), a.length(), b.length(), 0);
    System.out.println(maxLcs);
}

private static int lcs(char[] a, char[] b, int i, int j, int count) {
    if (i == 0 || j == 0)
        return count;
    if (a[i - 1] == b[j - 1]) {
        count = lcs(a, b, i - 1, j - 1, count + 1);
    }
    count = Math.max(count, Math.max(lcs(a, b, i, j - 1, 0), lcs(a, b, i - 1, j, 0)));
    return count;
}

}


0
投票

我在c ++中为此设计了一个递归解决方案。在我的方法中我采取一个特定的i,j,然后如果他们是相等的我加1并调用函数为i + 1,j + 1,而如果他们不相等我在相应的i存储零,j在我创建的2D数组中。执行后我打印2D数组,似乎没问题。因为我只是填充2D数组,我认为时间复杂度必须是O(mn),其中m是一个数组的长度,n是另一个数组。

//Finding longestcommonsubword using top down approach [memoization]
#include<iostream>
using namespace std;

int findlength(char A[], char B[], int i, int j, int st[][5], int r, int c){

if(r <= i)
  return 0;
else if(c <= j)
  return 0;
else{
    if(A[i] == B[j]){

        if(st[i][j] == -1)
        st[i][j] = 1+findlength(A, B, i+1, j+1, st, r, c);
    }else{
        st[i][j] = 0;
        int a = findlength(A, B, i, j+1, st, r, c);
        int b = findlength(A, B, i+1, j, st, r, c);
    }
}    

return st[i][j];
}

int main(){
int n,m;
cin>>n>>m;
char A[n],B[m];

for(int i = 0;i < n;i++)
  cin>>A[i];

for(int j = 0;j < m;j++)
  cin>>B[j];

int st[n][5];


for(int k = 0; k < n;k++){
    for(int l = 0; l< 5;l++){
       st[k][l] = -1;   
    }
}
findlength(A, B, 0, 0, st, n, 5);

for(int k = 0; k < n;k++){
    for(int l = 0; l< 5;l++){
      cout<<st[k][l]<<" ";
    }
    cout<<endl;
}

return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.