动态规划(最大公共子序列)

网上关于动态规划的资料很多,看了很多,总结如下:

求原字符串和其反串的最大公共子序列(不是子串,因为可以不连续)的长度(使用动态规划很容易求得) 

1)首先是要知道最长公共子序列的长度的动态规划方程

    设有字符串a[0...n],b[0...m],下面就是递推公式。字符串a对应的是二维数组num的行,字符串b对应的是二维数组num的列。

    

2、其次要看的懂求BDCABA与ABCBDAB的最大公共子序列

3、关键代码如下:

 1 package com.sxt.bean;
 2
 3 import java.util.Scanner;
 4
 5 public class Demo{
 6     public static void main(String[] args){
 7         Scanner scan = new Scanner(System.in);
 8         while(scan.hasNextLine()){
 9             String str = scan.nextLine();
10             String revStr = reverse(str);
11             int lcs = getLongestCommonSeq(str, revStr);
12             System.out.println(str.length()-lcs);
13         }
14     }
15     public static int getLongestCommonSeq(String str1, String str2){
16         int len1 = str1.length();
17         int len2 = str2.length();
18
19         int[][] c = new int[len1+1][len2+1];
20         for(int i=0; i<=len1; i++){
21             c[i][0] = 0;
22         }
23         for(int j=0; j<=len2; j++){
24             c[0][j] = 0;
25         }
26         for(int i=1; i<=len1; i++){
27             for(int j=1; j<=len2; j++){
28                 char char1 = str1.charAt(i-1);
29                 char char2 = str2.charAt(j-1);
30                 if(char1 == char2){
31                     c[i][j] = c[i-1][j-1]+1;
32                 }else{
33                     c[i][j] = max(c[i][j-1], c[i-1][j]);
34                 }
35                 System.out.print(c[i][j]+" ");
36             }
37             System.out.println();
38         }
39         //打印出公共子序列
40         char str[]= new char[100];
41         int index = c[len1][len2]-1;
42         System.out.print("子字符串为:");
43         for (int i = len1,j = len2; i>0&&j>0;)
44         {
45             if(str1.charAt(i-1) == str2.charAt(j-1))
46             {
47                 str[index--] = str1.charAt(i-1);
48                 i--;
49                 j--;
50                 System.out.print(str1.charAt(i));
51             }
52             else
53             {
54                 if(c[i][j-1]>c[i-1][j])
55                 {
56                     j--;
57                 }else
58                 {
59                     i--;
60                 }
61             }
62         }
63         System.out.println();
64         return c[len1][len2];
65     }
66
67     public static int max(int i1, int i2){
68         if(i1 > i2) return i1;
69         else return i2;
70     }
71
72     public static String reverse(String str){
73         String reverseStr = "";
74         for(int i=str.length()-1; i>=0; i--){
75             reverseStr += str.charAt(i);
76         }
77         return reverseStr;
78     }
79 }

参考资料:http://www.cnblogs.com/newpanderking/p/3946159.html

时间: 2024-10-28 19:18:23

动态规划(最大公共子序列)的相关文章

经典算法之动态规划--求最大公共子序列

作为新人,之前对C,C++了解的比较少,关于算法方面更是一窍不通,但最近却痴迷上了算法,哪怕是前辈们不屑一顾的东东,我弄明白了后都会欣喜若狂! 今天将遇到的问题和java实现贴出来和同为新人的博友分享,老鸟可以可以直接关网页了. 定义: 子序列:一个给定序列的子序列是再该序列中删去若干元素后得到的序列.即:给定{x1,x2,...,xm}和Z={z1,z2,...,zk},X的子序列是指存在一个严格递增下表序列{i1,i2,...ik} 使得对所有的j=1,2,...k,都有zj=xij.例如:

HDU 1159 Common Subsequence 最大公共子序列

Problem Description A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = <x1, x2, ..., xm> another sequence Z = <z1, z2, ..., zk> is a subsequence of X if there exists a stri

ACM最大公共子序列&amp;&amp;回文串

---恢复内容开始--- Description A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You are to write a program which, given a string, determines the minimal number of characters to be in

ACM 最大公共子序列

Description A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = < x1, x2, ..., xm > another sequence Z = < z1, z2, ..., zk > is a subsequence of X if there exists a strictly

hdu1159 最大公共子序列

题意就不用多说了       这道题就是求两个串的最大公共子序列  注意与最大公共子串的区别 最长公共子序列的结构 最长公共子序列的结构有如下表示: 设序列X=<x1, x2, -, xm>和Y=<y1, y2, -, yn>的一个最长公共子序列Z=<z1, z2, -, zk>,则: 1> 若 xm=yn,则 zk=xm=yn,且Zk-1是Xm-1和Yn-1的最长公共子序列: 2> 若 xm≠yn且 zk≠xm ,则 Z是 Xm-1和 Y的最长公共子序列:

python3 lcs 最大公共子序列

抛出问题: 假定字符串 s1 = 'BDCABA', s2 = 'ABCBDAB',求s1和s2的最大公共子序列. 问题分析: 我们想要求出s1和s2的最大公共子序列,我们可以用c(i,j)表示s1(i)和s2(j)最大公共子序列的长度,  假定c(i,j) = m,      如果:s1[ i ]和s2[ j ]相等,那么推出c(i,j) = c(i-1,j-1)  + 1, 如果:s1[ i ] 和 s2[ j ]不相等,那么得到c(i,j) = max(c(i,j-1),c(i-1,j))

spoj Longest Common Substring (多串求最大公共子序列)

题目链接: https://vjudge.net/problem/SPOJ-LCS 题意: 最多10行字符串 求最大公共子序列 数据范围: $1\leq |S| \leq100000$ 分析: 让他们都和第一个字符串匹配,算出每个字符串与第一个字符串的,以$i$位置(i指的是在s1中的位置)结尾匹配的最大长度 与其它字符串的匹配取最小值 最后对所有位置取最大值 超时代码:(题限是236ms,这个代码跑2000ms没问题) #include<bits/stdc++.h> #define ll l

求两个串的最大公共子序列的长度

1 public class CommonSubsequence { 2 3 public static int f(String s1,String s2){ 4 5 if(s1.length()==0||s2.length()==0) return 0; 6 7 if(s1.charAt(0)==s2.charAt(0)) 8 return f(s1.substring(1),s2.substring(1))+1; 9 else 10 return Math.max(f(s1.substri

Common Subsequence 最大公共子序列问题

Problem Description A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = <x1, x2, ..., xm> another sequence Z = <z1, z2, ..., zk> is a subsequence of X if there exists a stri