zoukankan      html  css  js  c++  java
  • 最长公共子序列之动态

    最长公共子序列(LCS)

    问题描述
    给定两个字符串,求解这两个字符串的最长公共子序列。
    如: S1={1,5,2,8,9,3,6},S2={5,6,8,9,3,7}
    其最长公共子序列为{5,8,9,3},最长公共子序列长度为4。

    思路分析
    1、分析问题的最优子结构性质
    在这里插入图片描述
    因此,两个序列的最长子序列包含了这两个序列的前缀的最长公共子序列。

    2、建立递推公式
    递推公式
    3、自底向上求解最优值

    **加粗样式**
    4、根据计算最优值时得到的信息,构造最优解

    代码演示

    #include <iostream>
    using namespace std;
    #define N 100
    int n,m;
    char S1[N],S2[N];
    int dp[N][N];
    int b[N][N];
    
    void LCSLength()
    {
    	for(int i=0;i<=n;i++)
    		for(int j=0;j<=m;j++){
    			dp[i][0]=0;
    			dp[0][j]=0;
    		}
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++){
    			if(S1[i]==S2[j]){
    				dp[i][j]=dp[i-1][j-1]+1;
    				b[i][j]=1;  
    			}
    			else if(dp[i-1][j]>dp[i][j-1]){
    				dp[i][j]=dp[i-1][j];
    				b[i][j]=2; 
    			}
    			else{
    				dp[i][j]=dp[i][j-1];
    				b[i][j]=3;
    			} 	
    		}
    }
    
    void LCS(int i,int j)
    {
    	if(i==0||j==0) 
    		return;
    	if(b[i][j]==1){
    		LCS(i-1,j-1);
    		cout<<S1[i]<<" ";//S2[j]
    	}
    	else if(b[i][j]==2)
    		LCS(i-1,j);
    	else
    		LCS(i,j-1);
    }
     
    int main()
    {
    	cin>>n;
    	for(int i=1;i<=n;i++)
    		cin>>S1[i];
    	cin>>m;
    	for(int i=1;i<=m;i++)
    		cin>>S2[i];
    	LCSLength();
    	cout<<"最长公共子序列长度是:"<<dp[n][m]<<endl;
    	cout<<"最长公共子序列是:"; 
    	LCS(n,m);
    	cout<<endl; 
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=m;j++)
    			cout<<dp[i][j]<<" ";
    		cout<<endl;
    	}
    	cout<<endl;
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=m;j++)
    			cout<<b[i][j]<<" ";
    		cout<<endl;
    	}
    }
    

    视频演示
    感觉讲的不错

  • 相关阅读:
    PL/SQL Developer使用技巧、快捷键(转发)
    Java 获取随机日期
    jsonArray和Java List对象互转,日期处理
    ExtJs grid单选,多选
    ExtJs 下拉单联动,次级下拉框查询模式
    ExtJs 日期相加,Grid表格列可编辑
    转:Java阳历转农历
    转:Java 计算2个时间相差多少年,多少个月,多少天的几种方式
    钥匙计数之一
    LianLianKan
  • 原文地址:https://www.cnblogs.com/Indomite/p/14195227.html
Copyright © 2011-2022 走看看