利用LCS(最长公共子串)解决方法来解决LPS问题:
首先用到了一个结论:对于串S, 假设它反转后得到的串是S', 那么S的最长回文串是S和S'的最长公共字串。 例如 S = babcbabcbaccba, S' = abccabcbabcbab,S和S'的最长公共字串是 abcbabcba也是S的最长回文字串。
存在问题:输入123321125775165561,输出165561。但是存在123321也是最长回文子串。不能确保唯一性。
/* //判断其是否唯一
if (res.length() >LPS(deleteSubString(string, res)).length()) {
System.out.println(res);
}else {
System.out.println(LPS(deleteSubString(string, res)));
System.out.println(res);
}*/
直接附上利用Java实现最长回文串的代码:
package Findwork;
import java.util.Scanner;
/**
* @author hadoop
* 最长回文字符串的问题 Longest palindrome string (LPS)
* 将字符串s1 进行翻转成 s2 然后寻找s2和s1的最长公共子串LCS
*
*/
public class LPString {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.print("Please input string for test LPS :");
Scanner s=new Scanner(System.in);
String string=s.next();
System.out.println(LCS(string, reverseString(string)));
s.close();
}
public static String reverseString(String str) {
if (str==null || str.equals("")) {
return str;
}
return str.charAt(str.length()-1)+reverseString(str.substring(0,str.length()-1));
}
public static String LCS(String str1, String str2)
{
//判断两个字符串是否为空
if(str1==null || str2 == null)
{ return null; }
if (str1.equals(" ") || str2.equals(" "))
{ return null; }
int xLen = str1.length(); // 将s1放在x轴方向 ,其串长度为列数clo,xlen
int yLen = str2.length(); // 将s2放在y轴方向 ,其串长度为行数row,ylen
int baseCow[]=new int [xLen]; //记录基础行
int curCow[] = new int [xLen]; //记录当前行
int maxLen =0; //记录最长子串长度,及当前矩阵中最大元素
int pos=0; //记录当前行最大元素的最大列数
char c=' ';
for (int i=0;i<yLen;i++) //遍历s2 ,Y 列方向
{
c =str2.charAt(i);
for(int j=0;j<xLen;j++) //比较S1,X行方向
{
if (c==str1.charAt(j))
{
//j为0时 第一列 没有左上角元素
if (j==0) {
curCow[j]=1;
}else {
//curCow[j]=curCow[j-1]+1; //这一句写错了
curCow[j]=baseCow[j-1]+1;
}
if (maxLen<curCow[j]) {
maxLen=curCow[j];
pos =j;
}
}
}
//每当s2中一个元素 比较完一次s1时 生成一个curRow , 将其赋给baseRow,然后清空
for (int k=0;k<xLen;k++)
{
baseCow[k]=curCow[k];
curCow[k]=0;
}
}
return str1.substring(pos+1-maxLen, pos+1); //substring c++和java 不同,java右边参数不包括, 记住这里找的是s1 , curRow找的是行
}
}
思考问题: 如何找出字符串中的所有回文字符串?
思路:先找出最长回文字符串L1,然后从中心遍历逐步输出子串;原串再截掉最长回文,再找最长回文,如此递归,直至找到的最长回文串为空;
解决最长回文字符串的方法2:(中心寻找法)
package Findwork;
import java.util.Scanner;
/**
* @author hadoop
*利用中心法寻找最长回文子串 其中循环的时候分为“单核”和“双核” string=findP(str, i, i); string=findP(str, i, i+1);
*/
public class LPString2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.print("Please input string for test LPS :");
Scanner s=new Scanner(System.in);
String string=s.next();
String res= LPS(string);
System.out.println(res);
s.close();
}
//中心法找回文字符串
public static String findP(String str,int left, int right) {
while (left >=0 && right<=str.length()-1&& str.charAt(left)==str.charAt(right))
{
left--;
right++;
}
return str.substring(left+1, right); //左闭右开区间
}
public static String LPS(String str) {
if (str.length()<=1) return str;
String res="";
String string;
for(int i=0;i<str.length()-1;i++)
{
string=findP(str, i, i);
if (res.length()<string.length()) {
res = string;
}
string=findP(str, i, i+1);
if (res.length()<string.length()) {
res = string;
}
}
return res;
}
}