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

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

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

输入字符串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"));

}

}

程序最终执行结果是:

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

上述实现过程中,用数组保存了所有的公共子串信息,然后排序取最大的子串,这种做法如果只是求最大子串的话,算法就不是很合理,因此做了如下修改,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"));

}

}

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

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

  1. 用java实现串匹配问题_java实现字符串匹配问题之求最大公共子串

    转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/38924981 最近在项目工作中有一个关于文本对比的需求,经过这段时间的学习,总结 ...

  2. java 蓝桥杯算法提高 字符串匹配(题解)

    试题 算法提高 字符串匹配 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 给出一个字符串和多行文字,在这些文字中找到字符串出现的那些行.你的程序还需支持大小写敏感选项:当选项打开时 ...

  3. 求两个字符串的LCS(最长公共子串)后缀数组

    题意: 给两个字符串,求出它们的最长公共子串的长度. 比如 yeshowmuchiloveyoumydearmotherreallyicannotbelieveit yeaphowmuchilovey ...

  4. c int转字符串_【C++实现python字符串函数库】字符串匹配函数startswith与endswith

    [C++实现python字符串函数库]字符串匹配函数startswith与endswith 这两个函数用于匹配字符串的开头或末尾,判断是否包含另一个字符串,它们返回bool值.startswith() ...

  5. java匹配两个字符_·代表任意一个字符,*代表任意一串字符,判断两个字符串是否匹配?...

    ·代表任意一个字符,*代表任意一串字符,判断两个字符串是否匹配? 如题,·代表任意一个字符,*代表任意一串字符,判断两个字符串是否匹配?假如a字符串为:as*bnc·b,b字符串为asdfgvbbnc ...

  6. php两个字符串公共,C++_C语言求两个字符串的最长公共子串,本文实例讲述了C语言求两个字 - phpStudy...

    C语言求两个字符串的最长公共子串 本文实例讲述了C语言求两个字符串的最长公共子串的方法.分享给大家供大家参考.具体实现方法如下: #include "stdio.h" #inclu ...

  7. 动态规划:求两个字符串的最长公共子序列

    问题描述:求两个字符串的最长公共子序列. 思路:使用动态规划的思想,将问题分解为小的子问题. 假设两个字符串序列分别为:X{x0, x1, x2,......, xm}, Y{y0, y1, y2,. ...

  8. 字符串分隔 【问题描述】 输入两个字符串str和cut。cut由若干个字符构成,其中每个字符均可作为一个分隔字符对str进行分隔。

    题头的话:长按点赞可私我赠送50+本C与C++书籍电子书资源 字符串分隔 [问题描述] 输入两个字符串str和cut.cut由若干个字符构成,其中每个字符均可作为一个分隔字符对str进行分隔. 注意: ...

  9. 写出一个程序,接受一个由字母和数字组成的字符串,和一个字符,然后输出输入字符串中含有该字符的个数。不区分大小写

    002-华为机试-在线测试 题目描述 写出一个程序,接受一个由字母和数字组成的字符串,和一个字符,然后输出输入字符串中含有该字符的个数.不区分大小写. 输入描述: 输入一个有字母和数字以及空格组成的字 ...

最新文章

  1. 安全篇:弱密码python检测工具
  2. 3_2 TemplateMethodMode 模板方法模式
  3. .NET Core 以及与 .NET Framework的关系
  4. svpwm矢量控制电机相电压波形_【顺藤摸瓜】永磁同步为什么要用SVPWM控制
  5. 论文浅尝 | 基于Universal Schema与Memory Network的知识+文本问答
  6. java+cache使用方法_java相关:springboot使用GuavaCache做简单缓存处理的方法
  7. imgaug批量椒盐噪声 python_python图像扩增-imgaug
  8. 【DB2】delete大表不记录日志的正确操作
  9. 迟到的 cocoapod 版本适配 之网利宝
  10. SpringMVC_04 拦截器 【拦截器的编程步骤】【session复习?】
  11. hadoop学习路线图
  12. 轴承过盈量程序matlab,轴承matlab处置程序.doc
  13. Ubuntu18.04 Deb 包安装方法
  14. O形橡胶密封圈设计标准
  15. 一名IT民工开通博客
  16. 纯java写2D格斗游戏(一)——界面背景设置及人物的简单设置
  17. 陈坤儿子的最新相关信息
  18. CCS2020论文泛读记录
  19. HDU4689 Prince and Princess (Tarjan+匈牙利匹配)
  20. 【老生谈算法】matlab实现遗传算法选取最优参数——遗传算法

热门文章

  1. Android view变形,android仿变形金刚效果实现MatchView
  2. php时间戳防盗链,金山云-文档中心-设置时间戳+共享密钥防盗链
  3. 整机压力测试_加湿器防水检测仪防水测试与气密性检测是怎么做的
  4. 软件项目周报_软件产品研发流程
  5. mysql出现can t_php运行提示Can't connect to MySQL server on 'localhost'的解决方法
  6. php object添加到数组,PHP Object转换为数组array
  7. java mvc引擎_Velocity是一种Java模版引擎技术,MVC架构的一种实现,但它更多的是关注在Model和View之间,作为它们的桥梁。服务端渲染,我们使用最多的就是用他...
  8. Aroma's Search(暴力)
  9. Dr. Evil Underscores(异或最大值最小)
  10. 建立一个laravel项目