用动态规划算法对最大子串问题的java实现

最大字串问题描述大概就是给定2个字符串,找出他们两个共有的最长字符串。比如一个是"tabcfg"另外一个"abckj"那么最大子串就是"abc".

动态规划算法最重要的就是分解问题,找出递归。说一下我的思考思路,首先拿到2个字符串,如何找到最长子串呢?

1.假设他们(字符串a,b)的头字母不相同的话,那么分别去掉首字母比较,也就是说用a.subString(1)和b比较,用 b.subString(1)和a比较,最长子字符串没变吧?答案是肯定的。ok递归出现了,结束条件就是有一个字符串变空,返回值就是a和b的最长子串。

b.假设他们头字母相同,那么一直比较下去,知道两者的第n个字母不相同,然后把前n-1个字母存为子字符串c,把a.subString(1)和b返回结果记为d,b.subString(1)和a返回结果记为e,那么返回c,d和e最长的一个(感谢lexy的评论,之前确实遗漏一种情况。不应该直接把前面的相同的去掉直接比较的,现在代码已经更新了)。

也许有人说应该从后面往前面比较,找到相同的然后一个个再往前比,其实道理都是一样的,关键要找到分解问题的方法。这里只是抛砖引玉,下面是具体的java实现。

import java.util.HashMap;
import java.util.Map;

/**
* @author HEACK
*
*/
public class CompareStr {

         /**
         * @param args
         */
         public static void main(String[] args) {
                 // TODO Auto-generated method stub
                 String str1 = "abcde1234567abcdefghijk";
                 String str2 = "abcdefgh12345";

                 //String str2 = "abc happyies dutcbirthday peter";
                 CompareStr cj = new CompareStr();
                 System.out.println(cj.getLongestString(str1,str2));

         }

         private boolean isEmpty(String str) {
                 return str == null || str.trim().length() == 0;
         }
         private Map map = new HashMap();

         private String getLongestString(String str1, String str2) {
                 if (isEmpty(str1) || isEmpty(str2)) {
                         return "";
                 }
                 StringBuffer key = new StringBuffer();
                 key.append(str1).append("&&").append(str2);
                 if (map.containsKey(key.toString())) {
                         return (String)map.get(key.toString());
                 }
                 StringBuffer longestStr = new StringBuffer();
                 char[] str1List = str1.toCharArray();
                 char[] str2List = str2.toCharArray();
                 int i = 0;
                 for (i = 0; i < str1List.length && i < str2List.length; i++) {
                         if (str1List[i] == str2List[i]) {
                                 longestStr.append(str1List[i]);
                         } else {
                                 break;
                         }
                 }
                 String subStr1 = str1.substring(i);
                 String subStr2 = str2.substring(i);
                 if (i == 0) {
                         String retStr1 = getLongestString(subStr1.substring(1), subStr2);
                         String retStr2 = getLongestString(subStr1, subStr2.substring(1));
                         String returnStr = retStr1.length() >= retStr2.length() ? retStr1 : retStr2;
                         map.put(key.toString(), returnStr);
                         return returnStr;
                 } else {
                         String retStr1 = getLongestString(str1.substring(1), str2);
                         String retStr2 = getLongestString(str1, str2.substring(1));
                         String retStr = retStr1.length() > retStr2.length() ? retStr1
                     : retStr2;
                         String returnStr = retStr.length() >= longestStr.toString().length() ? retStr
                                         : longestStr.toString();
                         map.put(key.toString(), returnStr);
                         return returnStr;
                 }
         }

}

HashMap用来存储已经计算过的字符串,用空间换时间。代码当然还可以优化,您也可以一试身手哦。

时间: 2024-10-28 14:03:35

用动态规划算法对最大子串问题的java实现的相关文章

动态规划算法

斐波纳契数列F(n) n 0 1 2 3 4 5 6 7 8 9 10 F(n) 1 1 2 3 5 8 13 21 34 55 89 递归 vs 动态规划 递归版本(太慢): int f(int n) { if(n <= 1) return 1; else return f(n-1)+f(n-2); } 动态规划版本(有效率!算法复杂度是 O(n)): int a[1000]; int f(int n) { a[0]=a[1]=1; for(int i=2; i<=n; i++) a[i]=

动态规划算法计算网络的最长路线和最短路线

/* * File: longest.c * Desciption: 动态规划算法计算网络的最长路线和最短路线 * Created: 2001/12/2 * Author: Justin Hou [mailto:justin_hou@hotmail.com] * */ #include <stdio.h> #define N 7 /* 顶点数目 */ #define I 999 /* 表示无穷大 */ int graph[N][N] = { /* 图的邻接矩阵 */ {I, 4, 5, 8,

五大常用算法之二:动态规划算法(DP)

一.基本概念     动态规划过程是:每次决策依赖于当前状态,又随即引起状态的转移.一个决策序列就是在变化的状态中产生出来的,所以,这种多阶段最优化决策解决问题的过程就称为动态规划. 二.基本思想与策略     基本思想与分治法类似,也是将待求解的问题分解为若干个子问题(阶段),按顺序求解子阶段,前一子问题的解,为后一子问题的求解提供了有用的信息.在求 解任一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解.依次解决各子问题,最后一个子问题就是初始问题的解.

【算法导论】动态规划算法之装配线调度

        和分治算法一样,动态规划是通过组合子问题的解而解决整个问题的.但是与分治算法不同的是,动态规划算法适用于子问题不是独立的情况,也就是各子问题包含公共的子子问题.动态规划通常用于最优化问题的求解.看一个问题是否适合采用动态规划算法,主要有两个标志:最优子结构和重叠子问题. 最优子结构:问题的一个最优解包含了子问题的最优解. 重叠子问题:当一个递归算法不断地调用同一问题时,我们说该最优子问题包含重叠子问题. 动态规划算法的设计步骤如下: 1.描述最优解的结构. 2.递归定义最优解的值

java算法-Longest Palindromic Substring 最长回文子串问题?JAVA

问题描述 Longest Palindromic Substring 最长回文子串问题?JAVA public class Solution { public String longestPalindrome(String s) { String ret = ""; for (int i = 0; i < s.length(); i++) { for (int j = 0; i - j >= 0 && i + j < s.length(); j++)

hashmap-Edmonds算法:最大权匹配的java实现

问题描述 Edmonds算法:最大权匹配的java实现 最近帮忙做一个课题任务,要求用java实现Edmonds算法. Edmonds算法的具体描述可以参阅百度文库的这篇文章:http://wenku.baidu.com/link?url=GVU282p9OTXuMPlFUy4eb_a_j-t2TO8HsHEh-rzPo0_y6txgB6jCuNGwBfhhWA1i87mrInc31Z4pIGp1mPPCJGCwPKLOcfpvLqz7_7QnFmS 要求输入:图的节点和带权边 要求输出:边的最

一些常见的递归算法 动态规划算法

最大值的递归算法 对于一个数组 有A[ 1...n ] 算法调用的时候调用max(n) max(i) if i = 1 return A[i] else if A[i]>max(i-1) return A[i] else return max(i-1) end if end if 平均值的递归算法 对于数组 a[ 1...n ] sum 初值为 0 index 初值则为1 调用该算法使用 Ave(a,sum,index) Ave(int a[],int sum,int index) if(ind

算法——动态规划算法

动态规划法基本思想:将原问题分解为相似的子问题,在求解的过程中通过子问题的解求出原问题的解.著名的应用实例有:求解最短路径问题,背包问题,项目管理,网络流优化等. 个人对动态规划的理解,主要就是避免重复计算.就是那些曾经发生过的事情,曾经计算过的值先保存下来,然后再次遇到相同的子问题的时候,直接用保存好的值给出,不再进行计算. 有一个很简单的例子,关于斐波那契数列.   什么是斐波那契数列?根据维基百科的解释是这样的, 费波那西数列(Fibonacci Sequence),又译费波拿契数.斐波那

动态规划算法--蛮力算法求最大子段和

问题: 给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],-,a[n],求该序列如a[i]+a[i+1]+-+a[j]的子段和的最大值.当所给的整均为负数时定义子段和为0,依此定义,所求的最优值为: Max{0,a[i]+a[i+1]+-+a[j]},1<=i<=j<=n 例如,当(a[1],a[2],a[3],a[4],a[5],a[6])=(-2,11,-4,13,-5,-2)时,最大子段和为20. 最大子段和是动态规划中的一种. 当b[j-1]>0时b[j]=