数据结构与算法

动态规划(一,最长公共子序列LCS算法)

2019-03-18  本文已影响1人  腊鸡程序员
50.jpg
概念:

动态规划是运筹学的一个分支,是求解决策过程最优化的数学方法.
原理:把多阶段过程转化为一系列单阶段过程,利用各阶段之间的关系,逐个求解.
特点:分析是从大到小,写代码是从小到大.计算过程中会把结果都记录下,最终结果在记录中找到.

例子:

求两个字符串的最长公共子序列(lcs算法).

字符串:
x:abcbdab
y:bdcaba

方法:
用一个二维数组表示

" " a b c b d a b
b 0 1 1 1 0 0 1
d 0 1 1 1 2 2 2
c 0 1 2 2 2 2 2
a 1 1 1 2 2 3 3
b 0 2 2 2 2 3 4
a 1 2 2 2 2 3 4

横向表示字符串x,纵向表示字符串y

解释一下:当最后一位相同,就把最后一位取出来,然后比较前面的,最后一位不相同就把最后一位去掉继续比较

写代码时我们先写a和b比较,然后我们比较ab和b,有相同的,我们保存b,然后比较ac和bc,以此类推

代码:
import org.junit.Test;

import java.util.Stack;

import static sun.swing.MenuItemLayoutHelper.max;

public class Lcs {

   public void lcs(String x,String y){
       char[] s1 = x.toCharArray();
       char[] s2 = y.toCharArray();
       int[][] array = new int[s1.length][s2.length];
       Stack<Character> stack = new Stack<>();

       //1.填表
       for (int i = 0; i < s1.length; i++) {
           for (int j = 0; j < s2.length; j++) {
               if (s1[i]==s2[j]){
                   if (i-1<0||j-1<0){
                       array[i][j] = 1;
                   }else {
                       array[i][j] = array[i-1][j-1]+1;
                   }
               }else {
                   if (i-1<0||j-1<0){
                       array[i][j] = 0;
                   }else {
                       array[i][j] = max(array[i-1][j],array[i][j-1]);
                   }
               }
           }
       }

       //打印
       for (int i = 0; i < array.length; i++) {
           for (int j = 0; j < array[0].length; j++) {
               System.out.print(array[i][j]+" ");
           }
           System.out.println();
       }

       //从后往前,将相同数据放入栈中
       int i = s1.length-1;
       int j = s2.length-1;

       while (i>=0&&j>=0){
           if (s1[i]==s2[j]){
               stack.push(s1[i]);
               i--;
               j--;
           }else {
               if (array[i-1][j]>array[i][j-1]){
                   i--;
               }else {
                   j--;
               }
           }
       }

       System.out.println("---------------------");

       while (!stack.isEmpty()){
           char s = stack.pop();
           System.out.print(s+" ");
       }
   }

   @Test
   public void Test(){
       lcs("bdcaba","abcbdab");
   }
}

上一篇 下一篇

猜你喜欢

热点阅读