转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/48974425
http://www.llwjy.com/blogdetail/46b46cdd7d80de938ac159922c0060ca.html
个人博客站已经上线了,网址 www.llwjy.com ~欢迎各位吐槽~
-------------------------------------------------------------------------------------------------
问题描述
在之前的一篇博客《java实现字符串匹配问题之求两个字符串的最大公共子串》中介绍了如何求两个字符串的公共子串,今天在网上看到一个问题,是求一个字符串的最大回文子串的,比如:
"a"的回文子串是"a"
"abac"的回文子串是"aba"
对于这个问题的实现,自己想通过已有公共子串来实现,具体思路如下:求字符串s1的最大回文子串,首先构造一个s1的反转字符串s2,然后求s1、s2的最大公共子串,求出的最大公共子串就是s1的最大回文子串(自己手动测试了很多事例,都是正确的,但是没有找到相关的理论支持)。
代码实现
在原有代码的基础上添加一个方法,具体如下:
public List<String> getPalindromeStr(String s) {
if (s == null || "".equals(s)) {
return null;
}
StringBuffer sb = new StringBuffer(s);
String s2 = sb.reverse().toString();
return getMaxChildString(s, s2);
}
该工具类完整代码如下:
/**
*@Description: 字符串的公共子串
*/
package com.lulei.util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class StringFactor {
private String str1;
private String str2;
private int maxLength = -1;
/**
* @param s1
* @param s2
* @return
* @Author:lulei
* @Description: 获取所有公共子串,并排序
*/
public List<String> getAllChildString(String s1, String s2) {
List<String> strs = new ArrayList<String>();
if (s1 == null || s2 == null) {
return strs;
}
this.str1 = s1;
this.str2 = s2;
//求所有公因子字符串,保存信息为相对第二个字符串的起始位置和长度
List<ChildString> childStrings = new ArrayList<ChildString>();
for (int i = 0; i < this.str1.length(); i++) {
getAllChildString(i, 0, childStrings);
}
for (int i = 1; i < this.str2.length(); i++) {
getAllChildString(0, i, childStrings);
}
//排序
sort(childStrings);
for (ChildString s: childStrings) {
strs.add(this.str2.substring(s.maxStart, s.maxStart + s.maxLength));
}
return strs;
}
/**
* @param s1
* @param s2
* @return
* @Author:lulei
* @Description: 获取最大公共子串
*/
public List<String> getMaxChildString(String s1, String s2) {
List<String> strs = new ArrayList<String>();
if (s1 == null || s2 == null) {
return strs;
}
this.str1 = s1;
this.str2 = s2;
//求所有公因子字符串,保存信息为相对第二个字符串的起始位置和长度
List<ChildString> childStrings = new ArrayList<ChildString>();
for (int i = 0; i < this.str1.length(); i++) {
getMaxChildString(i, 0, childStrings);
}
for (int i = 1; i < this.str2.length(); i++) {
getMaxChildString(0, i, childStrings);
}
for (ChildString s: childStrings) {
strs.add(this.str2.substring(s.maxStart, s.maxStart + s.maxLength));
}
return strs;
}
/**
* @param i
* @param j
* @param sortBean
* @Author:lulei
* @Description: 查找所有子串
*/
private void getAllChildString(int i, int j, List<ChildString> sortBean) {
int length = 0;
int start = j;
for (; i < this.str1.length() && j < this.str2.length(); i++,j++) {
if (this.str1.charAt(i) == this.str2.charAt(j)) {
length++;
} else {
//直接add,保存所有子串
if (length > 0) {
sortBean.add(new ChildString(length, start));
length = 0;
}
start = j + 1;
}
if (i == this.str1.length() - 1 || j == this.str2.length() - 1) {
//直接add,保存所有子串
if (length > 0) {
sortBean.add(new ChildString(length, start));
}
//对角线结尾,length置0
length = 0;
}
}
}
/**
* @param i
* @param j
* @param sortBean
* @Author:lulei
* @Description: 保存当前最大子串
*/
private void getMaxChildString(int i, int j, List<ChildString> sortBean) {
int length = 0;
int start = j;
for (; i < this.str1.length() && j < this.str2.length(); i++,j++) {
if (this.str1.charAt(i) == this.str2.charAt(j)) {
length++;
} else {
//下面的判断,只保存当前最大的子串
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 == this.str1.length() - 1 || j == this.str2.length() - 1) {
//下面的判断,只保存当前最大的子串
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
length = 0;
}
}
}
/**
*@Description: 公共子串类
*@Author:lulei
*@Version:1.1.0
*/
private class ChildString {
int maxLength;
int maxStart;
ChildString(int maxLength, int maxStart){
this.maxLength = maxLength;
this.maxStart = maxStart;
}
}
/**
* @param list
* @Author:lulei
* @Description: 降序排列
*/
private void sort(List<ChildString> list) {
Collections.sort(list, new Comparator<ChildString>(){
public int compare(ChildString o1, ChildString o2) {
return o2.maxLength - o1.maxLength;
}
});
}
/**
* @param s
* @return
* @Author:lulei
* @Description:返回字符串的最大回文子串
*/
public List<String> getPalindromeStr(String s) {
if (s == null || "".equals(s)) {
return null;
}
StringBuffer sb = new StringBuffer(s);
String s2 = sb.reverse().toString();
return getMaxChildString(s, s2);
}
public static void main(String[] args) {
String s1 = "refer";
String s2 = "ref";
System.out.println("--------------------------all--------------------------");
for (String s : new StringFactor().getAllChildString(s1, s2)) {
System.out.println(s);
}
System.out.println("--------------------------max--------------------------");
for (String s : new StringFactor().getMaxChildString(s1, s2)) {
System.out.println(s);
}
System.out.println("--------------------------huiwen--------------------------");
for (String s : new StringFactor().getPalindromeStr(s1)) {
System.out.println(s);
}
}
}
-------------------------------------------------------------------------------------------------
小福利
-------------------------------------------------------------------------------------------------
个人在极客学院上《Lucene案例开发》课程已经上线了(目前上线到第二课),欢迎大家吐槽~