当前位置: 首页 > news >正文

最长公共子序列--动态规划算法

考虑最长公共子序列问题如何分解成子问题,设A=“a0,a1,…,am-1”,B=“b0,b1,…,bn-1”,并Z=“z0,z1,…,zk-1”为它们的最长公共子序列。不难证明有以下性质:

(1) 如果am-1=bn-1,则zk-1=am-1=bn-1,且“z0,z1,…,zk-2”是“a0,a1,…,am-2”和“b0,b1,…,bn-2”的一个最长公共子序列;

(2) 如果am-1!=bn-1,则若zk-1!=am-1,蕴涵“z0,z1,…,zk-1”是“a0,a1,…,am-2”和“b0,b1,…,bn-1”的一个最长公共子序列;

(3) 如果am-1!=bn-1,则若zk-1!=bn-1,蕴涵“z0,z1,…,zk-1”是“a0,a1,…,am-1”和“b0,b1,…,bn-2”的一个最长公共子序列。

问题的递归式写成:

 

 

recursive formula

回溯输出最长公共子序列过程:

flow

package test;

import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName: LCS
 * @Description: TODO
 * @author:
 * @Date: 2015-06-29 12:50:14
 */
public class LCS {

    static int MAX=2;
    
    public static List<String> getLCS(int[][] c, int i, int j, String x, String y){
        List<String> t = new ArrayList<String>();
        if(i == 0 || j == 0){
            ;
        }else if(c[i][j] == 1){
            t = getLCS(c,i-1,j-1,x,y);
            if(t.size() == 0)
                t.add("");
            for(int k = 0; k < t.size(); k++){
                String v = t.get(k);
                if(v.length() > 0){
                    int it = Integer.parseInt(v.substring(v.lastIndexOf("(")+1,v.lastIndexOf(",")));
                    if(i - it > 2){
                        t.remove(k);
                        continue;
                    }
                    int jt = Integer.parseInt(v.substring(v.lastIndexOf(",")+1,v.lastIndexOf(")")));
                    if(j - jt > 2){
                        t.remove(k);
                        continue;
                    }
                }
                t.set(k, t.get(k) + x.charAt(i)+"("+i+","+j+")");
            }
        }else if(c[i][j] == 2){
            t = getLCS(c,i-1,j,x,y);
        }else if(c[i][j] == 3){
            t.addAll(getLCS(c,i-1,j,x,y));
            t.addAll(getLCS(c,i,j-1,x,y));
        }else{
            t = getLCS(c,i,j-1,x,y);
        }
        return t;
    }
    
    public static int LCSLength(int[][] c, int i, int j, byte[] xx, byte[] yy,int[][] max){
        
        if(i == 0 || j == 0){
            c[i][j] = 0;
        }else if(xx[i] == yy[j]){
            max[i][j] = 1;    
            c[i][j] = LCSLength(c,i-1,j-1,xx,yy,max)+1;
        }else {
            int ii = LCSLength(c,i-1,j,xx,yy,max);
            int jj = LCSLength(c,i,j-1,xx,yy,max);
            if(ii > jj)
                max[i][j] = 2;
            else if(ii == jj)
                max[i][j] = 3;
                
            c[i][j] = Math.max(ii,jj);
        }
        return c[i][j];
    }
    
    
    public static void main(String[] args){
        String x = " ABCBDAB";
        String y = " BDCABA";
        
        byte[] xx = x.getBytes();
        byte[] yy = y.getBytes();
        
        int c[][] = new int[x.length()][y.length()];
        int max[][] = new int[x.length()][y.length()];
        System.out.println(LCSLength(c,x.length()-1,y.length()-1,xx,yy,max));
        
        List<String> list  = getLCS(max,x.length()-1,y.length()-1,x,y);
        for(String v: list)
            System.out.println(v);
        System.out.print("\n  ");
        for(int j = 1; j < y.length();j++)
            System.out.print(y.charAt(j)+ " ");
        System.out.println("");
        for(int i = 1; i < x.length(); i++){
            System.out.print(x.charAt(i)+ " ");
            for(int j = 1; j < y.length();j++)
                System.out.print(c[i][j]+ " ");
            System.out.println(" ");
        }
        
    }
}

 

相关文章:

  • window.onload 与$(document).ready()的区别
  • 爱上OpenCL的十个理由
  • ionic之angular拦截器
  • 运行时间(Java版本)—转换毫秒到时分秒日期
  • hibernate_使用笔记
  • SharePoint 命令 安装、部署、回收、删除、更新 wsp包 (Solution)
  • Lisp-Stat 数据读取与绘图
  • 前后端分离了,然后呢?(转)
  • 向上取整和向下取整
  • oracle 抽取 对方大字段数据
  • Kubernetes初步
  • 谁是面向对象的设计霸主?(上)
  • Java 兑换ObjectC代码
  • [老老实实学WCF] 第三篇 在IIS中寄存服务
  • cocos2d 缓存池 对象的再利用
  • 《深入 React 技术栈》
  • 【跃迁之路】【585天】程序员高效学习方法论探索系列(实验阶段342-2018.09.13)...
  • 2017 前端面试准备 - 收藏集 - 掘金
  • Angular 响应式表单之下拉框
  • Angular2开发踩坑系列-生产环境编译
  • canvas 绘制双线技巧
  • CentOS7 安装JDK
  • CSS相对定位
  • Hexo+码云+git快速搭建免费的静态Blog
  • js ES6 求数组的交集,并集,还有差集
  • leetcode378. Kth Smallest Element in a Sorted Matrix
  • Lucene解析 - 基本概念
  • nginx(二):进阶配置介绍--rewrite用法,压缩,https虚拟主机等
  • PHP变量
  • Protobuf3语言指南
  • QQ浏览器x5内核的兼容性问题
  • springMvc学习笔记(2)
  • 如何设计一个微型分布式架构?
  • 入职第二天:使用koa搭建node server是种怎样的体验
  • 设计模式走一遍---观察者模式
  • 温故知新之javascript面向对象
  • 学习Vue.js的五个小例子
  • 【云吞铺子】性能抖动剖析(二)
  • ​ 无限可能性的探索:Amazon Lightsail轻量应用服务器引领数字化时代创新发展
  • ​sqlite3 --- SQLite 数据库 DB-API 2.0 接口模块​
  • (Mac上)使用Python进行matplotlib 画图时,中文显示不出来
  • (带教程)商业版SEO关键词按天计费系统:关键词排名优化、代理服务、手机自适应及搭建教程
  • (二)pulsar安装在独立的docker中,python测试
  • (十六)串口UART
  • (收藏)Git和Repo扫盲——如何取得Android源代码
  • (四)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)
  • (算法)Game
  • (转载)虚函数剖析
  • ***微信公众号支付+微信H5支付+微信扫码支付+小程序支付+APP微信支付解决方案总结...
  • .NET 6 Mysql Canal (CDC 增量同步,捕获变更数据) 案例版
  • .NET Core 版本不支持的问题
  • .NET/C# 避免调试器不小心提前计算本应延迟计算的值
  • .NET与java的MVC模式(2):struts2核心工作流程与原理
  • @Conditional注解详解
  • @WebService和@WebMethod注解的用法