最长公共子序列----java实现

package com.java.ly2011.June;

/**
 * 最长公共子序列
 *
 * f(na,nb) = 1 (a[na]==b[nb])                                                                         na==0||nb==0
 *                  0 (a[na]!=b[nb])
 * f(na,nb) = 1+f(na-1,nb-1)                                            (a[na]==b[nb])     na!=0&&nb!=0
 * f(na,nb) = max{ f(na-1,nb),f(na,nb-1)}                      (a[na]!=b[nb])       na!=0&&nb!=0
 *
 * @author Acer
 *
 */
public class LCS {
 
 private static int time;
 
 private static int getMax(int a , int b){
  return a>b?a:b;
 }
 
 /**
  *
  *
  * 从两个数组的最后一个元素开始比
  * 记住每次返回个结果之前一定要把结果记录到cache中
  * @param a
  * @param na a数组的起点
  * @param b
  * @param nb b数组的起点
  * @return
  */
 public static int DPLCS(int[] a ,int na,int[] b ,int nb , Integer[][] cache){
  time++;
  
  if(na ==0 || nb==0) {
   int result = a[na]==b[nb]?1:0;
   cache[na][nb] = result;
   return result;
   
  }
  else{
   if(a[na]==b[nb]){
    int result;
    if(cache[na-1][nb-1]!=null){
     result = 1 + cache[na-1][nb-1];
    }
    else
     result = 1 + DPLCS(a, na-1, b, nb-1, cache);
    cache[na][nb] = result;
    return result;
   }
   else{
    
    int result1;
    if(cache[na][nb-1]!=null)
     result1 = cache[na][nb-1];
    else
     result1= DPLCS(a, na, b, nb-1, cache);
    
    int result2;
    if(cache[na-1][nb]!=null)
     result2 = cache[na-1][nb];
    else
     result2 = DPLCS(a, na-1, b, nb, cache);
    
    int result = getMax(result1, result2);
    cache[na][nb] = result;
    return result;
    
   }
  }
 }
 
 /**
  * 从两个数组的最后一个元素开始比
  * 记住每次返回个结果之前一定要把结果记录到cache中
  * @param a
  * @param na a数组的起点
  * @param b
  * @param nb b数组的起点
  * @return
  */
 public static LcsInfo DPLCS2(int[] a ,int na,int[] b ,int nb , Integer[][] cache ,String[][] lssCache){
  time++;
  
  if(na ==0 || nb==0) {
   int result = a[na]==b[nb]?1:0;
   String lssResult =(a[na]==b[nb]?a[na]:"") +"";
   
   cache[na][nb] = result;
   lssCache[na][nb] = lssResult;
   
   LcsInfo li = new LcsInfo();
   li.num = result;
   li.lcs = lssResult;
   
   return li;
   
  }
  else{
   if(a[na]==b[nb]){
    int result;
    String lssResult;
    if(cache[na-1][nb-1]!=null){
     result = 1 + cache[na-1][nb-1];
     lssResult = lssCache[na-1][nb-1] + a[na];
    }
    else{
     LcsInfo li = DPLCS2(a, na-1, b, nb-1, cache ,lssCache);
     result = 1 + li.num;
     lssResult = li.lcs +a[na]   ;
    }
    cache[na][nb] = result;
    lssCache[na][nb] = lssResult;
    
    LcsInfo li = new LcsInfo();
    li.num = result;
    li.lcs = lssResult;
    
    return li;
   }
   else{
    
    int result1;
    String lssResult1;
    if(cache[na][nb-1]!=null){
     result1 = cache[na][nb-1];
     lssResult1 = lssCache[na][nb-1];
    }
    else{
     LcsInfo li= DPLCS2(a, na, b, nb-1, cache ,lssCache);
     result1 = li.num;
     lssResult1 = li.lcs;
    }
    int result2;
    String lssResult2;
    if(cache[na-1][nb]!=null){
     result2 = cache[na-1][nb];
     lssResult2 = lssCache[na-1][nb];
    }
    else{
     LcsInfo li = DPLCS2(a, na-1, b, nb, cache,lssCache);
     result2 = li.num;
     lssResult2 = li.lcs;
    }
    int result = getMax(result1, result2);
    String lssResult= result==result1?lssResult1:lssResult2;
    
    cache[na][nb] = result;
    lssCache[na][nb] = lssResult;
    
    LcsInfo li = new LcsInfo();
    li.num = result;
    li.lcs = lssResult;
    return li;
    
   }
  }
 }
 

 
 public static void main(String[] args) {
  
  int[] a = new int[]{2,4,6,7,8,5,3};
  int[] b = new int[]{4,3,2,7,8,6,5};
  
  /*
  int[] a = new int[]{2,3};
  int[] b = new int[]{2,3};
  */
  Integer[][] cache = new Integer[a.length][b.length];
  
  System.out.println(DPLCS(a, a.length-1, b, b.length-1, cache));
  System.out.println(time);
  time = 0;
  cache = new Integer[a.length][b.length];
  
  String[][] strings = new String[a.length][b.length];
  LcsInfo li = DPLCS2(a, a.length-1, b, b.length-1, cache, strings);
  System.out.println(li.num);
  System.out.println(time);
  System.out.println(li.lcs);

 }
 
}

class LcsInfo{
 public int num ;
 
 public String lcs;
 
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值