码迷,mamicode.com
首页 > 其他好文 > 详细

动态规划最长的回文序列

时间:2015-08-14 18:47:21      阅读:391      评论:0      收藏:0      [点我收藏+]

标签:

15-2(最长的回文序列) 回文(palindrome)它是一个正序和反向同一非空字符串。例如。全长1串,civic,racecar,aibohphobia他们是回文。设计一个有效的算法。文子序列。

比如,给定输入character,算法应该返回carac.算法的执行时间是怎么样的?

解题思路:首先我们要注意的是题目要求求出最长回文子序列,而不是子串

假设是子串。比方abcdebca,该回文子串长度为1,是当中随意一个字符,而回文子序列是abcdbca(abcebca).所以求子串和子序列有一些不同。下面方法仅仅适用求子序列,求子串方法因为题目没有要求,这里暂且不提了。(PS:有些人可能不清楚子串和子序列的差别,这是要特别注意的问题。)

详细方法:仅仅要把原字符串逆转后和原字符串比較而且利用求最长公共子序列的方式求出的LCS就可以得到最长回文子序列。

也就是说 求出的LCS=最长回文子序列。

代码例如以下

#include <iostream>
using namespace std;
#define N 9//输入您要推断的字符串字符数
char*strReversal(char*str)
{
	for (int i=0;i<N/2;i++)
	{
		swap(str[i],str[N-i-1]);
	}
   return str;
}
char *b[N+2][N+2]={NULL};
int c[N+2][N+2]={0};
void Lcs_Length(char *x, char *y) 
{
	for (int i=0;i<N;i++)
	{
		for (int j=0;j<N;j++)
		{
			if (x[i]==y[j])
			{
				c[i+1][j+1]=c[i][j]+1;
				b[i+1][j+1]="↖";
			} 
			else
			{
				if (c[i][j+1]>=c[i+1][j])
				{
					c[i+1][j+1]=c[i][j+1];
					b[i+1][j+1]="↑";
				} 
				else
				{
					c[i+1][j+1]=c[i+1][j];
					b[i+1][j+1]="←";
				}
			}
		}
	}
}
void PRINT_LCS(char*x,int i,int j)
{
	if (i==0||j==0)
	{
		return;
	}
	if (b[i][j]=="↖")
	{
		PRINT_LCS(x,i-1,j-1);
		cout<<x[i-1]<<" ";
	}
	else
	{
		if (b[i][j]=="↑")
		{
			PRINT_LCS(x,i-1,j);
		} 
		else
		{
			PRINT_LCS(x,i,j-1);
		}
	}
}
void main()
{//为了和书中代码吻合,数组第一个位置存放空字符。

char x[N+1]={0}; char y[N+1]={0}; char c; cout<<"提示:输入字符串之前。依据须要设置N大小"<<endl; cout<<"请输入须要推断的字符串:"<<endl; for (int i=0;i<N;i++) { cin>>c; y[i]=x[i]=c; } y[i]='\0';x[i]='\0'; strReversal(y);//反转字符串 cout<<"x="<<x<<endl; cout<<"y="<<y<<endl; Lcs_Length(x, y); PRINT_LCS(x,N,N); }

例子输出技术分享


最后总结:求LCS须要O(n2)时间,求字符串的逆转须要O(n)时间,总得来说本程序只须要O(n2)时间。这个问题还是较为简单的。不过把书中样例改改就可以得到所需结果。




版权声明:本文博客原创文章。博客,未经同意,不得转载。

动态规划最长的回文序列

标签:

原文地址:http://www.cnblogs.com/lcchuguo/p/4730819.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!