最长公共子序列问题采用了递归、备忘录和动态规划来解决,流水作业问题用了Johnson
java:
最长公共子序列:
import java.util.Arrays;
import java.util.Scanner;
public class LongestCommonSubseq {
static int[][] b = null;
static int[][] c = null;
static int[][] c1 = null;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("请输入第一个字符串:");
//输入的字符串是从char数组的下标1处开始
StringBuilder sb1 = new StringBuilder(" ");
sb1 = sb1.append(sc.next());
char[] str1 = sb1.toString().toCharArray();
System.out.print("请输入第二个字符串:");
StringBuilder sb2 = new StringBuilder(" ");
sb2 = sb2.append(sc.next());
char[] str2 = sb2.toString().toCharArray();
//测试样例
// char[] str1 = new char[]{' ', 'c', 'n', 'b', 'l', 'o', 'g', 's'};
// char[] str2 = new char[]{' ', 'b', 'e', 'l', 'o', 'n', 'g'};
b = new int[str1.length + 1][str2.length + 1];
c = new int[str1.length + 1][str2.length + 1];
c1 = new int[str1.length + 1][str2.length + 1];
//初始化数组,将其全部置位-1
initArray(c1);
System.out.print("\n备忘录方法求得最长公共子串长度为:");
System.out.println(LC1(str1, str2, str1.length - 1, str2.length - 1));
System.out.print("递归方法求得最长公共子串长度为:");
System.out.println(LC2(str1, str2, str1.length - 1, str2.length - 1));
int max = lcsLength(str1, str2, b);
System.out.print("动态规划法求得最长子序列长度为:" + max);
if(max > 0)
System.out.print(",最长子序列为:");
else
System.out.println(",无公共子序列");
//从右下往左上输出子串
lcs(str1.length - 1, str2.length - 1, str1, b);
sc.close();
}
public static int lcsLength(char[] x, char[] y, int[][] b) {
int m = x.length - 1;
int n = y.length - 1;
for (int i = 1; i <= m; i++) {
c[i][0] = 0;
}
for (int i = 1; i <= n; i++) {
c[0][i] = 0;
}
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (x[i] == y[j]) {
c[i][j] = c[i - 1][j - 1] + 1;
b[i][j] = 1;
} else {
if (c[i - 1][j] >= c[i][j - 1]) {
c[i][j] = c[i - 1][j];
b[i][j] = 2;
} else {
c[i][j] = c[i][j - 1];
b[i][j] = 3;
}
}
}
}
return c[m][n];
}
public static void lcs(int i, int j, char[] x, int[][] b) {
if (i == 0 || j == 0)
return;
if (b[i][j] == 1) {
lcs(i - 1, j - 1, x, b);
System.out.print(x[i]);
} else if (b[i][j] == 2)
lcs(i - 1, j, x, b);
else
lcs(i, j - 1, x, b);
}
//备忘录
static int LC1(char[] x, char[] y, int i, int j) {
if (c1[i][j] > -1)
return c1[i][j];
if (i == 0 || j == 0)
c1[i][j] = 0;
else if (x[i] == y[j])
c1[i][j] = LC1(x, y, i - 1, j - 1) + 1;
else
c1[i][j] = Math.max(LC1(x, y, i, j - 1), LC1(x, y, i - 1, j));
return c1[i][j];
}
//递归
static int LC2(char[] x, char[] y, int i, int j) {
if (i == 0 || j == 0)
return 0;
else if (x[i] == y[j])
return LC2(x, y, i - 1, j - 1) + 1;
else
return Math.max(LC2(x, y, i, j - 1), LC2(x, y, i - 1, j));
}
static void initArray(int[][] a) {
for (int[] ints : a)
Arrays.fill(ints, -1);
}
}
流水作业问题:
import java.util.Scanner;
public class Johnson {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("请输入作业个数:");
int n = s.nextInt();
int[] a = new int[n];
int[] b = new int[n];
int[] c = new int[n];
System.out.println("请输入第一道工序中每个作业的时间");
for(int i = 0; i < n; i++){
a[i] = s.nextInt();
}
System.out.println("请输入第二道工序中每个作业的时间");
for(int i = 0; i < n; i++){
b[i] = s.nextInt();
}
System.out.println("最短时间为:" + flowShop(a, b, c));
}
public static int flowShop(int[] a, int[] b, int[] c){
int n = a.length;
Element[] d = new Element[n];
for (int i = 0; i < n; i++) {
int key = a[i] > b[i] ? b[i] : a[i];
boolean job = a[i] <= b[i];
d[i] = new Element(key, i, job);
}
mergeSort(d);
int j = 0, k = n - 1;
for (int i = 0; i < n; i++) {
if(d[i].job)
c[j++] = d[i].index;
else
c[k--] = d[i].index;
}
j = a[c[0]];
k = j + b[c[0]];
for (int i = 1; i < n; i++) {
j += a[c[i]];
k = j < k ? k + b[c[i]] : j + b[c[i]];
}
return k;
}
public static class Element implements Comparable{
int key ;
int index;
boolean job;
private Element(int key, int index, boolean job){
this.key = key;
this.index = index;
this.job = job;
}
@Override
public int compareTo(Object o) {
int xkey = ((Element)o).key;
if(key < xkey)
return -1;
if(key == xkey)
return 0;
return 1;
}
}
//归并排序
static void merge(Comparable c[], Comparable d[], int l, int m, int r) {
int i = l, j = m + 1, k = l;
while ((i <= m) && (j <= r)) {
if (c[i].compareTo(c[j]) <= 0)
d[k++] = c[i++];
else
d[k++] = c[j++];
}
if (i > m)
for (int q = j; q <= r; q++) {
d[k++] = c[q];
}
else {
for (int q = i; q <= m; q++) {
d[k++] = c[q];
}
}
}
static void mergePass(Comparable a[], Comparable b[], int s, int len) {
int i = 0;
while (i <= len - 2 * s) {
merge(a, b, i, i + s - 1, i + 2 * s - 1);
i = i + 2 * s;
}
if (i + s < len) {
merge(a, b, i, i + s - 1, len - 1);
} else {
for (int j = i; j < len; j++) {
b[j] = a[j];
}
}
}
static void mergeSort(Comparable a[]) {
int len = a.length;
Comparable[] b = new Comparable[len];
int s = 1;
while (s < len) {
mergePass(a, b, s, len);
s += s;
mergePass(b, a, s, len);
s += s;
}
}
}
qq:1351006594