输出两个字符串的最长公共子串和最长公共子序列

输出两个字符串的最长公共子串和最长公共子序列。求解两个字符串的最长公共子串和最长公共子序列在方法上很接近,都是动态规划。只不过在递推方程上有一些不一样。

输出两个字符串的最长公共子串

#include <bits/stdc++.h>
using namespace std;

string LCS(string str1, string str2){
	if(str1.empty() || str2.empty()){
        return "";
    }
    
    int indexMax=0, maxn=0;
    vector<vector<int> > L(str1.size(), vector<int>(str2.size(),0) );   //全部初始化为0 
    //L[i][j]代表 str1[0~i-1]和str2[0~j-1] 的最长公共子串的长度   

    for(int i=0; i<str1.length(); i++){
        for(int j=0; j<str2.length(); j++){
            if(str1[i] == str2[j] ){
                if(i==0 || j==0){
                    L[i][j]=1;
                }
                else{
                    L[i][j]=L[i-1][j-1]+1; 
                }
            }
            //else 是str1[i]!=str2[j]的情况,这种情况下L[i][j]=0,由于初始化已经将其设置为0,所以这里不再写。

            //处理完L[i][j]之后,查看一下是否需要记录下来 
            if(L[i][j] > maxn){
                maxn=L[i][j];   //记录下最长公共子串的长度
                indexMax=i;		//记录下出现“最长公共子串”时的末尾字符的位置 
            }
        }
    }
    return str1.substr(indexMax+1-maxn, maxn);   
    //字符串截取的长度有(end-start+1) = maxn, 那么start = end+1-maxn  
    // indexMax - (indexMax+1-maxn) + 1 = maxn, maxn即为所截取的字符串的长度。
}  

int main(){
	string str1, str2;
	string cur;
	while( getline(cin,cur) ){
		if(str1.empty()) str1 = cur;
		else if(str2.empty()) str2 = cur;
		
		if(!str1.empty() && !str2.empty() ){  
			cout<< LCS(str1, str2) <<endl;
			
			str1.clear();
			str2.clear();
		}
		cur.clear();
	} 	
} 

  

输出两个字符串的最长公共子序列。公共子序列和公共子串的区别在于,序列不要求连续,子串要求是其在原串中是连续的。

猜你喜欢

转载自www.cnblogs.com/liugl7/p/11300442.html