LPS问题:找出字符串中的最长回文字符串

利用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;
	}
}

猜你喜欢

转载自blog.csdn.net/qq_28619473/article/details/88622404