动态规划--之--最长公共子字符串

package 动态规划;
import java.util.Scanner;
public class LogestCommonZiXuLie
{

public static void main(String[] args)
     {
      Scanner scan = new Scanner(System.in);
      while(scan.hasNextLine())
        {
          String str = scan.nextLine();
          String revStr = reverse(str);
          int lcs = getLongestCommonSeq(str, revStr);
          System.out.println("字符串长度: "+lcs);
        }
    }
  public static int getLongestCommonSeq(String str1, String str2)
   {
    int len1 = str1.length();
    int len2 = str2.length();

int[][] c = new int[len1+1][len2+1];
    for(int i=0; i<=len1; i++)
       {
         c[i][0] = 0;
       }
    for(int j=0; j<=len2; j++)
       {
        c[0][j] = 0;
       }
             //先遍历横坐标在遍历纵坐标在回溯时就要比较左边和上边的值时如果左边小于上边就要横坐标自减
           //就是对应的下面的j--或者i--判断选其一
     for(int i=1; i<=len1; i++)
        {
           for(int j=1; j<=len2; j++)
              {
                char char1 = str1.charAt(i-1);//取得第一个字符串的其中一个
                char char2 = str2.charAt(j-1);//取出第二个字符串的每一个与前一个的字符串其中一个比较
                if(char1 == char2)
                    {
                     c[i][j] = c[i-1][j-1]+1;
                    }

else{
                    c[i][j] = max(c[i][j-1], c[i-1][j]);
                   }
             //System.out.print(c[i][j]+" ");
             }
           //System.out.println();
     }

//打印出公共子序列
       char str[]= new char[100];
       int index = c[len1][len2]-1;//最长公共子字符串保存的下标
       //System.out.println("index = "+index);
      System.out.print("子字符串为:");
       for (int i = len1,j = len2; i>0&&j>0;)
           {
             if(str1.charAt(i-1) == str2.charAt(j-1))
               {
                  str[index--] = str1.charAt(i-1);
                  //横纵坐标都自减的目的是因为围绕对角线的公共子字符串最长
                  i--;
                  j--;
                  System.out.print(str1.charAt(i));
                 //System.out.print(" "+str[index+1]+" --");
                }
             else
               {
             //比较c[i][j]左边和上边的两个值
              if(c[i][j-1]>c[i-1][j])
                     {
                       j--;
                      }else
                      {
                       i--;
                      }
                  }
          }
          System.out.println();
         return c[len1][len2];
 }
//求两个数得最大值,可以用包里的Math函数,
public static int max(int i1, int i2)
{
if(i1 > i2) return i1;
else return i2;
}
//求得字符串得反字符串,也可以用函数求得
public static String reverse(String str)
{
String reverseStr = "";
for(int i=str.length()-1; i>=0; i--){
reverseStr += str.charAt(i);
}
return reverseStr;
}

}

时间: 2024-12-11 15:28:23

动态规划--之--最长公共子字符串的相关文章

使用后缀数组寻找最长公共子字符串JavaScript版

后缀数组很久很久以前就出现了,具体的概念读者自行搜索,小菜仅略知一二,不便讨论. 本文通过寻找两个字符串的最长公共子字符串,演示了后缀数组的经典应用. 首先需要说明,小菜实现的这个后缀数组算法,并非标准,只是借鉴了其中的思想. 小菜实现的算法,有两个版本,第一个是空间换时间,第二个是时间换空间. 空间换时间版本 1 /* 2 利用后缀数组获取两个字符串最长公共子字符串 3 空间换时间版本 4 @params 5 s1 String,要分析的字符串 6 s2 String,要分析的字符串 7 no

最长公共子字符串

给定两个字符串,找到最长的公共子字符串,比如String1=abc12dfe string2=abdec12dfab 所以公共子字符串为c12df. 思路:动态规划,以每个字符为尾字符. 代码: public class Main { //生成dp数组 public static int[][] getdp(char[] c1, char[] c2) { int len1 = c1.length; int len2 = c2.length; int[][] dp = new int[len1][

闭关修炼 动态规划1——最长公共子序列(UVA111)

经典算法题每日演练——第四题 最长公共子序列 (来自于转载:http://www.cnblogs.com/huangxincheng/archive/2012/11/11/2764625.html) 一: 作用 最长公共子序列的问题常用于解决字符串的相似度,是一个非常实用的算法,作为码农,此算法是我们的必备基本功. 二:概念 举个例子,cnblogs这个字符串中子序列有多少个呢?很显然有27个,比如其中的cb,cgs等等都是其子序列,我们可以看出 子序列不见得一定是连续的,连续的那是子串. 我想

【算法导论之七】动态规划求解最长公共子序列

一.动态规划的概念 动态规划(Dynamic Programming)是通过组合子问题的解而解决整个问题的.分治算法是指将问题划分成一些独立的子问题,递归地求解各子问题,然后合并子问题的解而得到原始问题的解,与此不同,动态规划适用于子问题不是独立的情况,也就是各个子问题包含公共的子问题.在这种情况下,采用分治法会做许多不必要的工作,即重复地求解公共地子问题.动态规划算法对每个子问题只求解一次,将其结果保存在一张表中,从而避免每次遇到各个子问题时重新计算答案. 动态规划通常应用于最优化问题.此类问

动态规划之最长公共子序列

我们之前提到过过动态规划的几个经典问题: 动态规划原理:http://blog.csdn.net/ii1245712564/article/details/45040037 钢条切割问题:http://blog.csdn.net/ii1245712564/article/details/44464689 矩阵链乘法问题:http://blog.csdn.net/ii1245712564/article/details/44464689 今天我们来看一下动态规划的另外一个经典问题:最长公共子序列(

动态规划专题 最长公共子序列

一些概念: (1)子序列: 一个序列A = a1,a2,--an,中任意删除若干项,剩余的序列叫做A的一个子序列.也可以认为是从序列A按原顺序保留任意若干项得到的序列. 例如: 对序列 1,3,5,4,2,6,8,7来说,序列3,4,8,7 是它的一个子序列.对于一个长度为n的序列,它一共有2^n 个子序列,有(2^n – 1)个非空子序列. 请注意:子序列不是子集,它和原始序列的元素顺序是相关的. (2)公共子序列 : 顾名思义,如果序列C既是序列A的子序列,同时也是序列B的子序列,则称它为序

动态规划解决最长公共子序列问题(转)

原文链接 动态规划法 经常会遇到复杂问题不能简单地分解成几个子问题,而会分解出一系列的子问题.简单地采用把大问题分解成子问题,并综合子问题的解导出大问题的解的方法,问题求解耗时会按问题规模呈幂级数增加. 解决思想: 为了节约重复求相同子问题的时间,引入一个数组,不管它们是否对最终解有用,把所有子问题的解存于该数组中,这就是动态规划法所采用的基本方法. [问题] 求两字符序列的最长公共字符子序列 问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后

动态规划解最长公共子序列问题(转)

 动态规划法 经常会遇到复杂问题不能简单地分解成几个子问题,而会分解出一系列的子问题.简单地采用把大问题分解成子问题,并综合子问题的解导出大问题的解的方法,问题求解耗时会按问题规模呈幂级数增加. 为了节约重复求相同子问题的时间,引入一个数组,不管它们是否对最终解有用,把所有子问题的解存于该数组中,这就是动态规划法所采用的基本方法. [问题] 求两字符序列的最长公共字符子序列 问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列

动态规划求最长公共子序列问题

#include<iostream> #include<string> #include<vector> using namespace std; //找两个子串str1,str2的最长公共子串substr void findLongestSubString(string &str1, string &str2, string &substr){ if (str1.empty() || str2.empty()){ return; } //定义二