java 字符串子串_java实现字符串匹配求两个字符串的最大公共子串

本文实例讲述了java实现求两个字符串最大公共子串的方法。分享给大家供大家参考,具体如下:

最近在项目工作中有一个关于文本对比的需求,经过这段时间的学习,总结了这篇博客内容:求两个字符串的最大公共子串。

算法思想:基于图计算两字符串的公共子串。具体算法思想参照下图:

fbd4cdeb5b4efb9a1b2948ff132b80f3.png

输入字符串S1:achmacmh    输入字符串S2:macham

第a步,是将字符串s1,s2分别按字节拆分,构成一个二维数组;

二维数组中的值如b所示,比如第一行第一列的值表示字符串s2和s1的第一个字节是否相等,若相等就是1,否则就是0,最终产生b所示的二维数组;

分别求二维数组中斜线上的公共因子(斜线为元素a右下角值,即a[i][j]的下一个元素是a[i+1][j+1];公共因子为1所在的位置构成的字符串);

对所有公共因子排序,返回最大的公共因子的值。

具体的实现代码如下所示:

package cn.lulei.compare;

import java.util.ArrayList;

import java.util.Collections;

import java.util.Comparator;

import java.util.List;

public class StringCompare {

private int a;

private int b;

public String getMaxLengthCommonString(String s1, String s2) {

if (s1 == null || s2 == null) {

return null;

}

a = s1.length();//s1长度做行

b = s2.length();//s2长度做列

if(a== 0 || b == 0) {

return "";

}

//设置匹配矩阵

boolean [][] array = new boolean[a][b];

for (int i = 0; i < a; i++) {

char c1 = s1.charAt(i);

for (int j = 0; j < b; j++) {

char c2 = s2.charAt(j);

if (c1 == c2) {

array[i][j] = true;

} else {

array[i][j] = false;

}

}

}

//求所有公因子字符串,保存信息为相对第二个字符串的起始位置和长度

List childStrings = new ArrayList();

for (int i = 0; i < a; i++) {

getMaxSort(i, 0, array, childStrings);

}

for (int i = 1; i < b; i++) {

getMaxSort(0, i, array, childStrings);

}

//排序

sort(childStrings);

if (childStrings.size() < 1) {

return "";

}

//返回最大公因子字符串

int max = childStrings.get(0).maxLength;

StringBuffer sb = new StringBuffer();

for (ChildString s: childStrings) {

if (max != s.maxLength) {

break;

}

sb.append(s2.substring(s.maxStart, s.maxStart + s.maxLength));

sb.append("\n");

}

return sb.toString();

}

//排序,倒叙

private void sort(List list) {

Collections.sort(list, new Comparator(){

public int compare(ChildString o1, ChildString o2) {

return o2.maxLength - o1.maxLength;

}

});

}

//求一条斜线上的公因子字符串

private void getMaxSort(int i, int j, boolean [][] array, List sortBean) {

int length = 0;

int start = j;

for (; i < a && j < b; i++,j++) {

if (array[i][j]) {

length++;

} else {

sortBean.add(new ChildString(length, start));

length = 0;

start = j + 1;

}

if (i == a-1 || j == b-1) {

sortBean.add(new ChildString(length, start));

}

}

}

//公因子类

class ChildString {

int maxLength;

int maxStart;

ChildString(int maxLength, int maxStart){

this.maxLength = maxLength;

this.maxStart = maxStart;

}

}

/**

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

System.out.println(new StringCompare().getMaxLengthCommonString("achmacmh", "macham"));

}

}

程序最终执行结果是:

b3ce5260b8a2a4fcd869841dfb971f58.png

对于两个文件的比对个人认为可以参照这种算法思想(自己现在并为实现),在日后的博客中将会写到。

上述实现过程中,用数组保存了所有的公共子串信息,然后排序取最大的子串,这种做法如果只是求最大子串的话,算法就不是很合理,因此做了如下修改,List只保存当前计算中最大的子串,具体实现如下:

/**

*@Description: 字符串比较

*/

package com.lulei.test;

import java.util.ArrayList;

import java.util.List;

public class StringCompare {

private int a;

private int b;

private int maxLength = -1;

public String getMaxLengthCommonString(String s1, String s2) {

if (s1 == null || s2 == null) {

return null;

}

a = s1.length();//s1长度做行

b = s2.length();//s2长度做列

if(a== 0 || b == 0) {

return "";

}

//设置匹配矩阵

boolean [][] array = new boolean[a][b];

for (int i = 0; i < a; i++) {

char c1 = s1.charAt(i);

for (int j = 0; j < b; j++) {

char c2 = s2.charAt(j);

if (c1 == c2) {

array[i][j] = true;

} else {

array[i][j] = false;

}

}

}

//求所有公因子字符串,保存信息为相对第二个字符串的起始位置和长度

List childStrings = new ArrayList();

for (int i = 0; i < a; i++) {

getMaxSort(i, 0, array, childStrings);

}

for (int i = 1; i < b; i++) {

getMaxSort(0, i, array, childStrings);

}

StringBuffer sb = new StringBuffer();

for (ChildString s: childStrings) {

sb.append(s2.substring(s.maxStart, s.maxStart + s.maxLength));

sb.append("\n");

}

return sb.toString();

}

//求一条斜线上的公因子字符串

private void getMaxSort(int i, int j, boolean [][] array, List sortBean) {

int length = 0;

int start = j;

for (; i < a && j < b; i++,j++) {

if (array[i][j]) {

length++;

} else {

//直接add,保存所有子串,下面的判断,只保存当前最大的子串

//sortBean.add(new ChildString(length, start));

if (length == maxLength) {

sortBean.add(new ChildString(length, start));

} else if (length > maxLength) {

sortBean.clear();

maxLength = length;

sortBean.add(new ChildString(length, start));

}

length = 0;

start = j + 1;

}

if (i == a-1 || j == b-1) {

//直接add,保存所有子串,下面的判断,只保存当前最大的子串

//sortBean.add(new ChildString(length, start));

if (length == maxLength) {

sortBean.add(new ChildString(length, start));

} else if (length > maxLength) {

sortBean.clear();

maxLength = length;

sortBean.add(new ChildString(length, start));

}

}

}

}

//公因子类

class ChildString {

int maxLength;

int maxStart;

ChildString(int maxLength, int maxStart){

this.maxLength = maxLength;

this.maxStart = maxStart;

}

}

/**

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

System.out.println(new StringCompare().getMaxLengthCommonString("abcdef", "defabc"));

}

}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/244140.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

读《伤心至死》兼谈恐怖悬疑小说的写作问题

收到鬼古女寄来的最新小说《伤心至死万劫》&#xff0c;这是他第三部长篇&#xff0c;上海人民出版社2005年10月出版&#xff0c;也是他《伤心至死》悬疑系列的第一部。我和鬼古女只在网上有过交流&#xff0c;据说这是一对旅居美国的神秘夫妇的笔名。我喜欢他的小说&#xff0…

java继承的举例_java继承实例

实例需求&#xff1a;实现一个名为Person的类和它的子类Employee&#xff0c;Manager是Employee的子类&#xff0c;设计一 个类Add()用于涨工资&#xff0c;普通员工一次能涨10%&#xff0c;经理能涨20%。具体要求如下:(1)Person类中的属性有&#xff1a;姓名name String(类型)…

与狼共舞的女钢琴家

刚看了法国传奇女钢琴家埃莱娜格里莫的自传《野变奏》&#xff08;上海教育出版社出版&#xff09;&#xff0c;很精彩。我有幸收藏到她几张原版的唱片&#xff0c;经常会拿出来听听。她是我喜欢的哈斯基尔、阿格里奇和皮雷斯等女钢琴家之后&#xff0c;我所知道的最年轻的女钢…

究竟谁在买书??

今天和孩子去美术馆附近的百花美术商店买绘画用品&#xff0c;顺便到了三联奋图书中心。<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />几年来&#xff0c;我对去书店是非常矛盾的。读点书的人&#xff0c;不去书店淘书显然有愧…

java 使用string_java中string怎么使用

展开全部以下是关于string的七种用法&#xff0c;注意哦&#xff0c;记得要时常去查看java的API文档&#xff0c;那个里面也有很详细32313133353236313431303231363533e78988e69d8331333363393033的介绍1>获取1.1&#xff1a;字符串中包含的字符数&#xff0c;也就是字符串的…

情人节的第一道小点心

情人节“蕉叶”泰国餐厅的第一道小点心&#xff0c;用芭蕉叶包的西米露甜点&#xff0c;乍看像两个蜡烛&#xff0c;一黄一白&#xff0c;细看又似两个人的皮肤&#xff0c;一深一淡。绵软、清凉&#xff0c;入口即融&#xff0c;妙不必言。

与孩子去航空博物馆

北京航空博物馆草地广场——主题&#xff1a;四面楚歌&#xff0c;草木皆兵&#xff0c;红装小女&#xff0c;信步闲庭。航空博物馆的一个角落——主题&#xff1a;灰色里的一点红&#xff0c;肃杀中的一抹暖意

java 操作序列_JAVA序列化操作详解

一、概述很多时候我们需要将对象的信息以文件的形式存储到硬盘上以便以后可以恢复使用。我们可以按照一定的格式将变量的值依次写到特定格式的文件中。但有时候我们希望只有我们自己可以读懂它并且修改它&#xff0c;这就是序列化的作用。概念&#xff1a;将对象转化为字节序列…

为女儿示范的两张石膏像素描

26年没画了&#xff0c;为了给女儿学习石膏素描&#xff0c;示范一下&#xff0c;斗胆画了两张。材料&#xff1a;复印纸&#xff0c;4B铅笔&#xff0c;用时30分钟。这是一周前画的。材料&#xff1a;普通稿纸&#xff0c;2B铅笔&#xff0c;用时25分钟。用我当时少年宫美术老…

你好,弗朗索瓦丝·萨冈

“世界上只有两种东西最出名&#xff0c;新小说和萨冈。萨冈是个作家&#xff0c;是法国的通俗小说家&#xff0c;世界上所有的国家都翻译了她的作品。”“新小说”派的掌门人罗伯-格里耶如是说。格里耶肯定不喜欢萨冈&#xff0c;但是他所鼓吹的“新小说”绝对没有萨冈有名。一…

java中类与类的关系_Java中类与类的关系

在java中类和类的关系大致分三种&#xff1a;泛化、关联、依赖。1. 泛化(Generalization)"XX是一个XX"关系(is a),通常使用的关键词为 extends、implements继承:继承是面向对象最显著的一个特性。继承是从已有的类中派生出新的类&#xff0c;新的类能吸收已有类的数据…

徐坤用话剧震了我们一道

年前&#xff0c;徐坤为人艺小剧场写了个话剧《性情男女》&#xff0c;请几个朋友去看&#xff0c;要求是必须携夫人或者女朋友前往。我开始没明白她的用意&#xff0c;就带女朋友去了。剧场门口&#xff0c;徐坤穿着小红羽绒袄诡秘地迎接我们。 当我走进小剧场时&#xff0c;一…

《命犯桃花》离斯蒂芬·金还很遥远

期待已久的丁天的新书《命犯桃花》&#xff08;北方文艺出版社2006年2月&#xff09;终于出版了。在这之前他的2000年的旧作《脸》也刚刚修订再版。《脸》作为国内恐怖小说的开先河之作&#xff0c;在当时产生了很大的影响&#xff0c;甚至可以说影响了现在的一批恐怖小说作家。…

java spring redis_spring配置redis(xml+java方式)

条件&#xff1a;引用好架包org.springframework.dataspring-data-redis2.1.3.RELEASEredis.clientsjedis2.9.0一、使用xml进行配置1、创建xml文件2、使用&#xff1a;ApplicationContext applicationContext new ClassPathXmlApplicationContext("application.xml"…

我们需要什么样的恐怖小说?

斯蒂芬金漫画像 ——由台湾的两部有影响的恐怖小说谈起 台湾的恐怖悬疑类小说的发展比大陆早若干年&#xff0c;原本以为他们会写的好一些&#xff0c;可看了两本部曾被台湾书界追捧的恐怖小说&#xff0c;感觉非常失望。一本是《网络凶邻》&#xff08;作家出版社2006年2月出版…

男人是消耗品,女人是战利品?

读日本作家村上龙的随笔《所有的男人都是消耗品》&#xff08;上海译文出版社2006年2月出版&#xff09;,感觉颇有意趣。村上龙与另个村上&#xff08;春树&#xff09;几乎同龄&#xff0c;是日本战后经济高速发展时期成名的作家&#xff0c;在文坛并称“W村上”。两人虽是好友…

看“意大利文艺复兴艺术展”(1)

带女儿去中华世纪坛&#xff0c;看了“意大利文艺复兴艺术展”&#xff0c;展览管理非常严格&#xff0c;不许带包&#xff0c;不许拍照&#xff0c;进场时要经过类似机场的检查。不过&#xff0c;我偷拍了几张照片。。。。。帕拉德与人头马   波提切利 画

java 什么是servlet_JavaWeb解释一下什么是 servlet?

Servlet是一种独立于平台和协议的服务端的java技术&#xff0c;可以生成动态WEB页面与传统的CGI(计算机图形接口)和其他类似的CGI技术相比。Servlet具有更好的可移植性。更强大的功能&#xff0c;更少的投资&#xff0c;更高的效率&#xff0c;更好的安全性。servlet是使用java…

看“意大利文艺复兴艺术展”(3)

手提哥利亚头的大卫 卡拉瓦乔 画看着那些过去只能在画册上见到的名画&#xff0c;看着画面上岁月留下的细细的裂纹&#xff0c;感觉这些大师就像小时候常说的——“远在天边&#xff0c;近在眼前”。看来画一定要近距离的观赏才是&#xff0c;尤其是大师的作品。那些大面积…