Java教程

算法设计与分析:流水线问题和最长公共子序列(Java)

本文主要是介绍算法设计与分析:流水线问题和最长公共子序列(Java),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

最长公共子序列问题采用了递归、备忘录和动态规划来解决,流水作业问题用了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

这篇关于算法设计与分析:流水线问题和最长公共子序列(Java)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!