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 increasing sequence < i1, i2, ..., ik > of indices of X such that for all j = 1,2,...,k, xij = zj. For example, Z = < a, b, f, c > is a subsequence of X = < a, b, c, f, b, c > with index sequence < 1, 2, 4, 6 >. Given two sequences X and Y the problem is to find the length of the maximum-length common subsequence of X and Y.

Input

The program input is from the std input. Each data set in the input contains two strings representing the given sequences. The sequences are separated by any number of white spaces. The input data are correct.

Output

For each set of data the program prints on the standard output the length of the maximum-length common subsequence from the beginning of a separate line.

Sample Input

abcfbc         abfcab
programming contest
abcd mnp

Sample Output

4
2
0

Common Subsequence

求最大子序列的问题:

递推关系:c[][]存储最长子序列长度

$$ c[i][j] = \begin{cases} 0 &\ i = 0,\ \ j = 0 \\ c[i - 1][j - 1] + 1 &\ i > 0, j > 0; str\_x[i] = str\_y[j] \\ \max ( c[i][j - 1],\ c[i - 1][j] ) &\ i > 0, j > 0; str\_x[i] \ne str\_y[j] \end{cases} $$

AC代码:

import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str1, str2;
while (sc.hasNext()){
str1 = sc.next();
str2 = sc.next();
System.out.println(LcsLength(str1.toCharArray(), str2.toCharArray()));
}
sc.close();
} public static int LcsLength(char a[], char b[]){
int aL = a.length;
int bL = b.length;
int ans[][] = new int[aL + 1][bL + 1];
for (int i = 0; i <= aL; i++) {
ans[i][0] = 0;
}
for (int i = 0; i <= bL; i++) {
ans[0][i] = 0;
}
for (int i = 1; i <= aL; i++) {
for (int j = 1; j <= bL; j++) {
if (a[i - 1] == b[j - 1])
ans[i][j] = ans[i - 1][j - 1] + 1;
else if (ans[i][j - 1] >= ans[i - 1][j])
ans[i][j] = ans[i][j - 1];
else
ans[i][j] = ans[i - 1][j];
}
}
return ans[aL][bL];
}
}

可以输出最长子序列之一的代码:

import java.util.Scanner;

public class Main {

    public static int x[][];

    public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str1, str2;
while (sc.hasNext()) {
str1 = sc.next();
str2 = sc.next();
System.out.println("最大子序列长度: " + LcsLength(str1.toCharArray(), str2.toCharArray()));
}
sc.close();
} public static int LcsLength(char a[], char b[]) {
int aL = a.length; // a数组的长度
int bL = b.length; // b数组的长度
int ans[][] = new int[aL + 1][bL + 1]; // 存储i,j当前的最长子序列长度
x = new int[aL + 1][bL + 1]; // 存储ans[i][j]是斜对角还是左边,上边来的
for (int i = 0; i <= aL; i++) {
ans[i][0] = 0; // 空的子序列都为0
}
for (int i = 0; i <= bL; i++) {
ans[0][i] = 0; // 空的子序列都为0
}
for (int i = 1; i <= aL; i++) {
for (int j = 1; j <= bL; j++) {
if (a[i - 1] == b[j - 1]) { // 判断字符是否相等
ans[i][j] = ans[i - 1][j - 1] + 1; // 相等长度加1
x[i][j] = 1; // 标记为相等斜着来的
} else if (ans[i][j - 1] >= ans[i - 1][j]) { // 左边大于上边就用最大的
ans[i][j] = ans[i][j - 1];
x[i][j] = 2; // 标记为左边来的
} else {
ans[i][j] = ans[i - 1][j];
x[i][j] = 3; // 标记为上边来的
}
}
}
System.out.print("最大子序列: ");
Lcs(aL, bL, a);
System.out.print('\n'); return ans[aL][bL];
}
// 递归输出最大子序列其中一个
public static void Lcs(int i, int j, char a[]) {
if (i == 0 || j == 0)
return;
if (x[i][j] == 1) {
Lcs(i - 1, j - 1, a);
System.out.print(a[i - 1]);
} else if (x[i][j] == 2)
Lcs(i, j - 1, a);
else if (x[i][j] == 3)
Lcs(i - 1, j, a);
}
}

最新文章

  1. Modelsim-altera 仿真 顶层原理图的解决办法
  2. UNIX操作系统和Linux操作系统介绍
  3. spring-data-elasticsearch整合elasticsearch
  4. 你或许不了解的C++函数调用(1)
  5. 将Mat类型转换成QImage类型
  6. weka数据挖掘拾遗(三)----再谈如果何生成arff
  7. cf公式专场-续
  8. codeforces 633C. Spy Syndrome 2 hash
  9. UVA11983 - Weird Advertisement(扫描线)
  10. Oracle:如何使用PL/SQL 11.0连接远程Oracle12c服务器?
  11. leetcode 283. Move Zeroes -easy
  12. 什么是 Message Queue
  13. 微信小程序拒绝授权,反复调起原生授权框。
  14. Linux内核中常用的数据结构和算法(转)
  15. 「洛谷5290」「LOJ3052」「十二省联考 2019」春节十二响【启发式合并】
  16. 音频标签化2:youtube-8m项目的训练、评估与测试
  17. Oracle11g_OCM 课堂教学目录表
  18. 自己动手编译Linux内核
  19. ShardedJedis的使用
  20. Spring框架的事务管理之基于AspectJ的XML方式(重点掌握)

热门文章

  1. Golang数组和切片的区别
  2. &lt;audio&gt; 标签
  3. day71:drf:API接口&amp;Restful API规范&amp;Django Rest Framework&amp;drf中的序列化和反序列化功能
  4. 一口气看完45个寄存器,CPU核心技术大揭秘
  5. 如何使用FastCGI处理自定义HTTP头
  6. 基于ssm的客户管理系统
  7. 微信小程序picker组件两列关联使用方式
  8. JUC---08ForkJion(分支合并)
  9. CodeForces 1093F Vasya and Array
  10. 对Python&quot;一切皆对象&quot;的小参悟