Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.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
String 最长公共子串:递归解决方案?_String_Algorithm_Recursion_Dynamic Programming - Fatal编程技术网

String 最长公共子串:递归解决方案?

String 最长公共子串:递归解决方案?,string,algorithm,recursion,dynamic-programming,String,Algorithm,Recursion,Dynamic Programming,常用的子串算法: LCS(x,y) = 1+ LCS(x[0...xi-1],y[0...yj-1] if x[xi]==y[yj] else 0 现在,人们已经很好地理解了动态规划的解决方案。然而,我无法找出递归解决方案。如果有多个子字符串,则上述算法似乎失败 例如: 应用上述算法 1+ (x= "LABFQD" and y = "LABD") 1+ (x= "LABFQ" and y = "LAB") return 0 since 'Q'!='B' 返回的值应该

常用的子串算法:

LCS(x,y) = 1+ LCS(x[0...xi-1],y[0...yj-1] if x[xi]==y[yj]
           else 0
现在,人们已经很好地理解了动态规划的解决方案。然而,我无法找出递归解决方案。如果有多个子字符串,则上述算法似乎失败

例如:

应用上述算法

1+ (x=  "LABFQD" and y = "LABD")
1+ (x=  "LABFQ" and y = "LAB")
return 0 since 'Q'!='B'
返回的值应该是2,而我应该是3

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

long max\u sub(int i,int j)
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];
}
{ 如果(i=0和dp[i][j-1]=-1) max_sub(i,j-1); 返回dp[i][j]; }
代码的问题似乎您没有尝试所有的n^2可能性

包算法动态

公共类最长公共子字符串{

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

我在C++中设计了一个递归解。在我的方法中,我取一个特定的i,j,然后如果它们相等,我就加1并调用i+1,j+1的函数,而如果它们不相等,我就在我创建的2D数组中对应的i,j处存储一个零。在它执行之后,我正在打印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;
}
//使用自上而下的方法查找最长的CommonSubword[记忆]
#包括
使用名称空间std;
整数长度(字符A[],字符B[],整数i,整数j,整数st[][5],整数r,整数c){
如果(rn>>m;
字符A[n],B[m];
对于(int i=0;i>A[i];
对于(int j=0;j>B[j];
国际标准[n][5];
对于(int k=0;k请尽量避免混淆,您要问的是
最长公共子串
,而不是
最长公共子串
,它们非常相似,但是

下面是没有应用记忆的代码,以便更好地说明算法

public int-lcs(int[]A,int[]B,int-m,int-n,int-res){
如果(m==-1 | n==-1){
返回res;
}
如果(A[m]==B[n]){
res=lcs(A,B,m-1,n-1,res+1);
}
返回max(res,max(lcs(A,B,m,n-1,0),lcs(A,B,m-1,n,0));
}
公共int longestCommonSubString(int[]A,int[]B){
返回lcs(A,B,A.长度-1,B.长度-1,0);
}

以下是最长公共子字符串的递归代码:

int LCS(string str1, string str2, int n, int m, int count)
{
    if (n==0 || m==0)
        return count;
    if (str1[n-1] == str2[m-1])
        return LCS(str1, str2, n-1, m-1, count+1);
    return max(count, max(LCS(str1, str2, n-1, m, 0), LCS(str1, str2, n, m-1, 0)));
}

您能否进一步描述此解决方案解决此问题的原因?欢迎使用堆栈溢出。在此处回答问题很好,但一段没有解释的代码不是很有用。请在回答中包括对其功能、工作原理以及如何回答原始问题的解释。请解释您正在做的事情。我们如何添加记住它。
import sun.jvm.hotspot.types.CIntegerType;

class RespObject {
    public int len;
    public boolean isSubString;
    int maxLen;

    public RespObject(int len, boolean isSubString, int maxLen) {
        this.maxLen = maxLen;
        this.len = len;
        this.isSubString = isSubString;
    }
}

public class LongestCommonSubstring {
    public static void longestCommonSubstring(String str1, String str2, int i, int j, RespObject resp) {
        if ((j == str2.length()) || (i == str1.length())) {
            resp.isSubString = false;
            resp.len = 0;
            return;
        }
        int currLen = 0;
        longestCommonSubstring(str1, str2, i + 1, j, resp);
        RespObject respObject1 = resp;
        longestCommonSubstring(str1, str2, i, j + 1, resp);
        RespObject respObject2 = resp;
        if (str1.charAt(i) == str2.charAt(j)) {
            longestCommonSubstring(str1, str2, i + 1, j + 1, resp);
            resp.len += 1;
            currLen = resp.len;
            resp.isSubString = true;
        } else {
            resp.len = 0;
            resp.isSubString = false;
        }
        resp.maxLen = Integer.max(Integer.max(respObject1.maxLen, respObject2.maxLen), currLen);
    }

    public static void main(String[] args) {
        RespObject respObject = new RespObject(0, false, Integer.MIN_VALUE);
        longestCommonSubstring("dSite:Geeksf", "wSite:GeeksQ", 0, 0, respObject);
        System.out.println(respObject.len + "   " + String.valueOf(respObject.isSubString) + "  " + respObject.maxLen);
    }
}
The recursive method for finding longest common substring is:
Given A and B as two strings, let m as the last index for A, n as the last index for B.

    if A[m] == B[n] increase the result by 1.
    if A[m] != B[n] :
      compare with A[m -1] and B[n] or
      compare with A[m] and B[n -1] 
    with result reset to 0.
int LCS(string str1, string str2, int n, int m, int count)
{
    if (n==0 || m==0)
        return count;
    if (str1[n-1] == str2[m-1])
        return LCS(str1, str2, n-1, m-1, count+1);
    return max(count, max(LCS(str1, str2, n-1, m, 0), LCS(str1, str2, n, m-1, 0)));
}
     int max; //This gloabal variable stores max substring length
     int[][]dp; // 2D Array for Memoization

     void main(){
     //--------Main method just intended to demonstrate initialization---------

     dp = new int[m+1][n+1] //m and n are string length
     lcs(String a,String b,int n,int m)
     }
     
     //---++++++++-----Recrsive Memoized Function------++++++++++++-------
     static int lcs(String a,String b,int n,int m){
     
     if(dp[n][m]!=-1)return dp[n][m];
    
     if(n==0||m==0)return dp[n][m]=0;
     
     
     if(a.charAt(n-1)==b.charAt(m-1))
     {
        int res=0;int i=n-1,j=m-1;
        while((i>=0&&j>=0)&&a.charAt(i)==b.charAt(j)){
            res++;
            if(i==0||j==0)return dp[n][m] = Math.max(res,max);
            i--;j--;
        }
        max=Math.max(res,max);
        
        return dp[n][m]=Math.max(max,Math.max(lcs(a,b,n-res,m),lcs(a,b,n,m-res)));
         
     }
     
     return dp[n][m]=Math.max(lcs(a,b,n-1,m),lcs(a,b,n,m-1));
     
     
     
 }