java lcs矩阵,LCS算法的两种JAVA实现方式
给定字符串A,B
Solution I:
1.构造数组 c i j 描述A串的前i位和B串的前J位的LCS长度
2.构造数组 trace i j 描述max相应位置得到的长度是由哪一步得出的
c的构造方法根据下列规则
trace的构造如下图所示
END和START表示该处是直接得到的结果,没有前置步骤。
END表示LCS=0,START表示LCS=1
其余的根据箭头方向来看就比较好理解了。
获得结果时从上往下遍历即可,总的时间复杂度O(mn)+O(m+n)
代码如下
//枚举
enum DIRECTION{
LEFT,UP,UPLEFT,START,END
}
//核心算法
...
for(int i=0;i
for(int j=0;j
if(ch1[i]!=ch2[j]){
if(i>0&&j>0){
if(c[i-1][j]>c[i][j-1]){
trace[i][j]=DIRECTION.LEFT;
c[i][j]=c[i-1][j];
}
else{
trace[i][j]=DIRECTION.UP;
c[i][j]=c[i][j-1];
}
}else{
if(i>0){
trace[i][j]=DIRECTION.LEFT;
c[i][j]=c[i-1][j];
}else if(j>0){
trace[i][j]=DIRECTION.UP;
c[i][j]=c[i][j-1];
}else{
trace[i][j]=DIRECTION.END;
c[i][j]=0;
}
}
}else{
if(i==0||j==0){
trace[i][j]=DIRECTION.START;
c[i][j]=1;
}
else{
trace[i][j]=DIRECTION.UPLEFT;
c[i][j]+=c[i-1][j-1]+1;
}
}
}
//calculate
StringBuilder sb=new StringBuilder("");
int i=ch1.length-1,j=ch2.length-1;
end:
for(;i>=0&&j>=0;)
switch(trace[i][j]){
case UP:j--;break;
case LEFT:i--;break;
case UPLEFT:sb.append(ch1[i]);j--;i--;break;
case START:sb.append(ch1[i]);break end;
case END:break end;
}
//输出(sb.reverse().toString());
//输出(c[ch1.length-1][ch2.length-1]);
Solution II:
构造矩阵L(p,m)
算法实现方式不复杂,原理并不是很明了,这里把过程详细描述一下,希望可以得到一些讨论。
首先假设A串长度不超过B串。
构造基于A串长度的方阵L(i,k)表示A[1..i]中长度为k的子串在B中最小位置(这里认为字符串的位置是最末尾字符的位置),如果不存在这样的子串,则长度为无穷(MAX)。
显然,LCS={k|L(A.length,k)!=MAX}max。
过程也是从下至上递推的。
首先初始化L(1,i),注意L(i,k)=k时,L(i,k+1),L(i,k+2)....均为k,因为相同长度的子串,位置最小的一定是从头开始的那一个。
然后循环,遍历并生成L,规则如下:
i>k时,显然,L(i,k)=MAX
如果L(i-1,k-1)存在,则
从L(i-1,k-1)+1开始遍历到B串结尾,遍历的位置记为j,若B[j]=A[i],则:
比较L(i-1,k)(如果存在)和J的大小,较小的一个即为所求的L(i,k)
这里因为上一步所求的结果中,L(i-1.k-1)实际上可以看做L(i,k)的一部分,因为如果前者(长度为k-1的LCS)存在的话,在L(i-1.k-1)所得的位置往后遍历,遇到与A[i]相等的字符,一定可以与前者组成长度为k的LCS。
L(i,k)=k时,L(i,k+1),L(i,k+2)....均为k,原因同上。
对于一个k,遍历i一遍后,所有L(i,k)均不存在,则k-1,即最后一次所得的k,即为我们要的LCS长度。
B[L(1,m-p+1)]B[L(2,m-p+2)]…B[L(k,i)]即为LCS。
代码如下:
int result=0;
//Li(k)
int[][] L=new int[char1.length+1][char1.length+1];
//init L[k][i] k=1
for(int i=1;i<=char1.length;i++){
L[1][i]=1+str2.indexOf(String.valueOf(char1[i-1]));
if(L[1][i]==1){
for(int j=i+1;j<=char1.length;j++)
L[1][j]=1;
break;
}
}
int nullCount=0;
for(int k=2;k<=char1.length;k++){
nullCount=0;
for(int i=1;i<=char1.length;i++){
if(i
L[k][i]=MAX;
nullCount++;
continue;
}
int min=MAX;
if(L[k-1][i-1]!=MAX){
if(L[k][i-1]!=MAX)
min=L[k][i-1];
for(int j=L[k-1][i-1]+1;j<=char2.length;j++)
if(char2[j-1]==char1[i-1]){
min=j
break;
}
}
L[k][i]=min;
if(L[k][i]==k){
for(int j=i+1;j<=char1.length;j++)
L[k][j]=k;
break;
}
if(L[k][i]==MAX)
nullCount++;
}
if(nullCount==char1.length){
result=k-1;
break;
}
}
result=result==0?char1.length:result;
StringBuilder sb=new StringBuilder();
int i=char1.length,k=result;
while(k>0&&i>0)
sb.append(char2[L[k--][i--]-1]);
sb.reverse();
java lcs矩阵,LCS算法的两种JAVA实现方式相关推荐
- Java编译和执行模式包括两种,Java程序的编译和执行模式包括2点,是【 】和半解释。...
参考答案如下 植物的根瘤().A. 有助于根的吸收作用B.可提高土壤酸性c.有固氮作用D. 可产生维生素,程序促进根系 关于水流,编2点以下正确的是:()A.流向是指水流流去的方向B.流向是指水流流来 ...
- 算法:两种步长的希尔排序算法
算法:两种希尔排序算法 1 /** 2 * 希尔排序 3 * 不同步长的算法 4 * @author mackxu 5 * 6 */ 7 class ShellSort { 8 private int ...
- Java中的string定义的两种方法和区别
java中的String定义的两种方法和区别 第一种:new方式 String s1 = new String("hello world"); String s2 = new St ...
- java项目打jar包的两种情况
java项目打jar包的两种情况 本文介绍一下java项目打jar包时的两种情况各怎么操作 方法/步骤 1. 1 一.java项目没有导入第三方jar包 这时候打包就比较简单: 1. 首先在Ecl ...
- Java中线程的创建有两种方式
Java中继承thread类与实现Runnable接口的区别 Java中线程的创建有两种方式: 1. 通过继承Thread类,重写Thread的run()方法,将线程运行的逻辑放在其中 2. 通过 ...
- Java中两种抛出异常的方式
Java中两种抛出异常的方式 在Java中有两种抛出异常的方式,一种是throw,直接抛出异常,另一种是throws,间接抛出异常. 直接抛出异常是在方法中用关键字throw引发明确的异常.当thro ...
- 迪杰斯特拉【dijkstra】算法的两种实现和简单的正确性理解
先来讲一下迪杰斯特拉算法的正确性,即为什么按照迪杰斯特拉的那套逻辑来就能找到起点到终点的最短距离? 这个其实逻辑的内核其实是和用广搜来求最短路径是一样一样的,举一个形象的例子: 你见过会长矮的树嘛?嘿 ...
- Java生成二维码的两种方法
本文介绍Java生成二维码的两种方法,这两种方法都依赖于google提供的二维码依赖包. 一种是自己写工具类,代码可以网上抄. 另一种是使用hutool第三方工具类的依赖包,不用自己抄代码. 一.自定 ...
- Pytorch两种模型保存方式
以字典方式保存,更容易解析和可视化 Pytorch两种模型保存方式 大黑_7e1b关注 2019.02.12 17:49:35字数 13阅读 5,907 只保存模型参数 # 保存 torch.save ...
- android登录加密传输,android环境下两种md5加密方式(示例代码)
在平时开发过程中,MD5加密是一个比較经常使用的算法,最常见的使用场景就是在帐号注冊时,用户输入的password经md5加密后,传输至server保存起来.尽管md5加密经经常使用.可是md5的加密 ...
最新文章
- HDU 1406 完数
- 【三个臭皮匠】第一次网络会议记录
- Python学习之While--break
- Linux下 jenkins的安装
- Adobe Acrobat 9.0“ PDFMaker无法找到Adobe PDF Printer 的打印驱动程序”解决办法
- php连接mysql开发环境_PHP开发环境搭建及常用的数据库操作
- DB2 sql复制error sqlcode2038
- Timus 1015. Test the Difference!
- 【技巧】LeetCode 86. Partition List
- 怎么做应力应变曲线_金属薄板塑性应变比ISO 10113:2020 解读
- 鼠标在滑块上滚轮控制_直线导轨(滚轮导轨)与线轨(滚珠导轨)的优劣势对比...
- 拓端tecdat|R语言基于协方差的SEM结构方程模型中的拟合指数
- Ubuntu 下为 Idea 创建启动图标.
- 技嘉h310主板前置音频没声音_电脑前置插孔没声音 前置音频没声音解决方法
- 用大O记号法测量算法的效率(Algorithm efficiency Asymptotic notation Big O notation)
- sql函数—Lpad、Rpad
- C++程序练习-1008:Maya Calendar-玛雅日历
- 利用python爬取租房信息网_python实战计划:爬取租房信息
- 虚幻引擎4初探(UE4)
- Beego-HelloWorld