LCS(最长公共子序列)

求两个字符串的最长公共子序列的长度(子序列不一定是原串中的连续子串组成)
LCS

使用动态规划


#include <iostream>
#include <string>
#include <vector>

using namespace std;

int lcs_len(string s1, string s2)
{

    int len1 = s1.size(), len2 = s2.size();
    if (len1==0 || len2==0)
        return 0;
    //定义二维数组dp[i][j]  代表串1从0~i这段与串2从0~j这段的公共子串的最大值
    //赋初值dp[0~len1][0]=0   dp[0][0~len2]=0
    vector<vector<int> > dp(len1+1, vector<int>(len2+1,0));

    for (int i = 1; i <=len1; i++)
        {
        for (int j = 1; j <=len2; j++)
        {
            if (s1[i - 1] == s2[j - 1])
            {
                //若相等则上层值+1
                dp[i][j] = dp[i - 1][j - 1] + 1;
            }
            else{
                //若不相等则等于交错值中的最大值
                dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
            }
        }

    }
    return dp[len1][len2];
}

//测试函数
int main()
{
        string s1, s2;
        while (cin >> s1 >> s2)
        {
          cout << lcs_len(s1, s2) << endl;
        }
    return 0;
}


测试样例:



最长公共子串

输入例子:

abcde

abgde

输出例子:
2

解题思路:

这题其实是动态规划的变形经典题型,应用动态规划的思想,创建一个二维数组dp[n][n],其中dp[i][j],表示取到s1[i]和取到s2[j]时的最大连续子串长度。如果s1[i]等于s2[j],则dp[i-1][j-1]等于取到s1[i-1]和取到s2[j-1]时的最大连续子串长度加1,即

dp[i][j]=dp[i-1][j-1]+1。


下面直接上代码:
#include <stdio.h>
#include <string.h>
#define N 50
int main(){
    char s1[N],s2[N];
    int dp[N][N],i,j,max_len=0;
    gets(s1);
    gets(s2);
    for(i=0;i<strlen(s1);i++){
    	for(j=0;j<strlen(s2);j++){
    		if(s1[i]==s2[j]){
		    	if(i>0&&j>0){
	    			dp[i][j]=dp[i-1][j-1]+1;
	    		}else{
		    		dp[i][j]=1;
		    	}
		    	if(max_len<dp[i][j]){
	    			max_len=dp[i][j];
	    		}
		    }
	    }
    }
    printf("%d\n",max_len);
	return 0;
} 




猜你喜欢

转载自blog.csdn.net/ac_blood/article/details/79883756