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

转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/38924981

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

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

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

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

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

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

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

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

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<ChildString> childStrings = new ArrayList<ChildString>();
		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<ChildString> list) {
		Collections.sort(list, new Comparator<ChildString>(){
			public int compare(ChildString o1, ChildString o2) {
				return o2.maxLength - o1.maxLength;
			}
		});
	}

	//求一条斜线上的公因子字符串
	private void getMaxSort(int i, int j, boolean [][] array, List<ChildString> 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"));
	}
}

程序最终执行结果是:

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

时间: 2024-10-05 05:06:39

java实现字符串匹配问题之求最大公共子串的相关文章

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

转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/38924981 近期在项目工作中有一个关于文本对照的需求,经过这段时间的学习,总结了这篇博客内容:求两个字符串的最大公共子串. 算法思想:基于图计算两字符串的公共子串.详细算法思想參照下图: 输入字符串S1:achmacmh    输入字符串S2:macham 1)第a步,是将字符串s1,s2分别按字节拆分,构成一个二维数组: 2)二维数组中的值如b所看到的,比方第一行第一列的值

【Java编程】Java中的字符串匹配

在Java中,字符串的匹配可以使用下面两种方法: 1.使用正则表达式判断字符串匹配 2.使用Pattern类和Matcher类判断字符串匹配 正则表达式的字符串匹配: 正则表达式:定义一组字符串的一系列字符和符号,它由常量字符和特殊符号构成. 下面是正则表达式的一些预定义字符类,实际上是一些转义字符序列: 1.\d   代表任何数字 2.\D  代表任何非数字字符 3.\w  代表任何单字字符(如:字母.数字.下划线等等) 4.\W  代表任何非单字字符 5.\s   代表任何空白字符 6.\S

字符串匹配算法分析及Java实现

字符串模式匹配算法(string searching/matchingalgorithms) 顾名思义,就是在一个文本或者较长的一段字符串中,找出一个或多个指定字符串(Pattern),并返回其位置.这类算法属基础算法,各种编程语言都将其包括在自带的String类函数中,而且由之衍生出来的正则表达式也是必须掌握的一种概念和编程技术. Brute-Force算法 其思路很简单:从目标字符串初始位置开始,依次分别与Pattern的各个位置的字符比较,如相同,比较下一个位置的字符直至完全匹配:如果不同

Hash——字符串匹配(求s1在s2中出现的次数)

题目描述: 这是一道模板题. 给定一个字符串 A 和一个字符串 B ,求 B 在 A  中的出现次数.A 和 B中的字符均为英语大写字母. 求A 在 B 中出现了几次.(可重叠) 样例输入: 3 BAPC BAPC AZA AZAZAZA VERDI AVERDXIVYERDIAN 样例输出: 1 3 0 首先要知道什么是字符串hash(滚动哈希): 单哈希可以O(m)的时间计算长度为m的字符串的哈希值,但对于本题,总的时间复杂度没有改观.时间会爆. 这时我们就需要一个叫做滚动哈希的优化技巧.

Substrings(hdu1238)字符串匹配

Substrings Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7205 Accepted Submission(s): 3255 Problem Description You are given a number of case-sensitive strings of alphabetic characters, find the

HDU 1711 Number Sequence(字符串匹配)

Number Sequence Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 10571    Accepted Submission(s): 4814 Problem Description Given two sequences of numbers : a[1], a[2], ...... , a[N], and b[1],

KMP算法解决字符串匹配

该算法由D.E.Knuth ,J.H.Morris和 V.R.Pratt提出,用于解决字符串匹配问题. 思想: 设目标串(主串)为s,模式串为t ,并设i指针和j指针分别指示目标串和模式串中正待比较的字符,设i和j的初值均为0.若有s[i]=t[j],则i和j分别加1.否则,i不变,j退回到j=next[j-1]的位置,再比较s[i]和t[j],若相等,则i和j分别加1.否则,i不变,j再次退回到j=next[j]的位置,依此类推.直到下列两种可能: 1. 模式串t中的字符全部匹配,则出现频率+

【Foreign】字符串匹配 [KMP]

字符串匹配 Time Limit: 10 Sec  Memory Limit: 256 MB Description Input Output Sample Input 3 3 6 3 1 2 1 2 3 2 3 1 3 6 3 1 2 1 2 1 2 3 1 3 6 3 1 1 2 1 2 1 3 1 3 Sample Output 3 1 2 4 4 1 2 3 4 3 2 3 4 HINT Source 发现题目中颜色的具体权值是对答案无关的,然后就是只要相对位置一样即可. 那么显然是一个

C语言之基本算法41—字符串匹配问题

//字符串匹配问题 /* =============================================================== 题目:输入两字符串S,T,输出在S中存在但在T中不存在的字符存储到新的字符串中, 并保持其在字符串S中的顺序,然后在屏幕上显示新的字符串的内容. =============================================================== */ #include<stdio.h> #include<st