最长回文算法2

问题:

求给定输入字符串的最长回文子序列(子序列不要求连续)。

用LPS(i,j)表示从字符串第i个字符到第j个字符的最长回文子序列的长度,字符串的长度为n,则要求LPS(1,n),则:

LPS(i,j)=0; i>j;

LPS(i,j)=1; i==j;

LPS(i,j)=LPS(i+1,j-1)+2; str[i]==str[j];

LPS(i,j)=max(LPS(i+1,j),LPS(i,j-1)); str[i]!=str[j];

// zuichanghuiwen2.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<iostream>
#include<string>
using namespace std;
int c[20][20];
void LPS(string str)
{
	int m = str.length();
	int j;
	for (int j = 0; j < m; j++)
		for (int i = j + 1; i < m; i++)
			c[i][j] = 0;
	for (int i = 0; i < m; i++)
		c[i][i] = 1;
	for(int l=2;l<=m;l++)       //这里一定要按长度从短开始算
		for (int i = 0; i<m-l+1; i++)
		{
			j = i + l - 1;
			if (str[i] == str[j])
				c[i][j] = c[i + 1][j - 1] + 2;
			else
				c[i][j] = c[i + 1][j] > c[i][j - 1] ? c[i + 1][j] : c[i][j - 1];
		}
}

void rebuild(string str)
{
	int m = c[0][str.length() - 1];
	int mi;
	for (auto i = 0; i < str.length(); i++)
		if (str[i] == str[i + m - 1]) {
			mi = i;
			break;
		}
	for (int i = mi; i < mi + m; i++)
		cout << str[i];
}

int main()
{
	string str("dgdfgdfabcacbagfgfg");
	LPS(str);
	rebuild(str);
	while (1);
    return 0;
}

  

时间: 2024-10-13 01:40:40

最长回文算法2的相关文章

MANACHER最长回文算法

博客已经搬家,请前往http://gqqnbig.me/ 阅读格式良好的文章. 本文将一步一步构造Manacher算法,心急的一定看不懂!请先练习下面的习题. 探索最长回文串性质 题1:已知字符串以center为中心对称,求完整的字符串. abcd??? | center 答 abcdcba | center 题2:接上题,abcdcba后面还有一些字符,以center2为中心,最大对称半径[ref]半径大于等于1.[/ref]为7,求完整的字符串. 答根据center2的对称性质,可以知道字符

HDU 3068 最长回文 (manacher算法)

最长回文 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 9188    Accepted Submission(s): 3159 Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 回文就是正反读都是一样的字符串,如aba, abba等 Input 输入有多组

最长回文---hdu3068 (回文串 manacher 算法模板)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068 题意很清楚:就是求一个串s的子串中最长回文串的长度:这类题用到了manacher算法 manacher算法(复制大神的解释): 定义数组p[i]表示以i为中心的(包含i这个字符)回文串半径长 将字符串s从前扫到后for(int i=0;i<strlen(s);++i)来计算p[i],则最大的p[i]就是最长回文串长度,则问题是如何去求p[i]? 由于s是从前扫到后的,所以需要计算p[i]时一定

Manacher算法----最长回文子串

题目描述 给定一个字符串,求它的最长回文子串的长度. 分析与解法 最容易想到的办法是枚举所有的子串,分别判断其是否为回文.这个思路初看起来是正确的,但却做了很多无用功,如果一个长的子串包含另一个短一些的子串,那么对子串的回文判断其实是不需要的.同时,奇数和偶数长度还要分别考虑. Manacher算法可以解决上述问题,并在O(n)时间复杂度内求出结果.下面我们来看一下Manacher算法. 首先,为了处理奇偶的问题,在每个字符的两边都插入一个特殊的符号,这样所有的奇数或偶数长度都转换为奇数长度.比

[hiho 01]最长回文子串、Manacher算法

题目描述 - 基础方法:枚举子串,判断是否为回文串. - 改进:枚举中间位置,向两侧拓展. - 再改进:利用以前的信息,使得不用每个新位置都从长度1开始拓展. - 优化:将字符串预处理为奇数长度以避免考虑条件分支. - 再优化:开头加入特殊字符避免考虑边界. Manacher 算法: id 是中心点,mx 是其边界.P[i] 表示以 i 为中心的最长回文子串的折半长度. 只要 i < mx, 以 i 为中心的回文子串就可以不必从长度1开始找,而从min{P[j], mx - i}开始(其中j为i

hdu-3068 最长回文 【Manacher算法】

Manacher算法学习资料:http://blog.csdn.net/dyx404514/article/details/42061017 最长回文 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 9282    Accepted Submission(s): 3194 Problem Description 给出一个只由小写英文字符

1112个人赛,最长回文串常见算法讨论

ps.此贴大部分文字与代码来自网上,我只是取长补短整理了下 S=“c a b a”  那么  S' = “a b a c”, 这样的情况下 S和 S‘的最长公共子串是aba.没有错误. 但是当 S=“abacdfgdcaba”, 那么S’ = “abacdgfdcaba”. 这样S和S‘的最长公共子串是abacd.很明显abacd并不是S的最长回文子串,它甚至连回文都不是. 现在是不是都明白为什么最长回文子串不能转化成为最长公共子串问题了.当原串S中含有一个非回文的串的反序串的时候,最长公共子串

HDU - 3068 最长回文(manacher算法)

题意:给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 分析: manacher算法: 1.将字符串中每个字符的两边都插入一个特殊字符.(此操作的目的是,将字符串长度统一变成奇数,道理很容易想---奇数+偶数=奇数or偶数+奇数=奇数) eg:abba--->#a#b#b#a# 此外,为了便于处理边界,可在字符串开始处再加另外一个特殊字符. eg:#a#b#b#a#--->$#a#b#b#a# 2.数组 P[i] 来记录以字符S[i]为中心的最长回文子串向

manacher求最长回文子串算法

原文:http://www.felix021.com/blog/read.php?2040 首先用一个非常巧妙的方式,将所有可能的奇数/偶数长度的回文子串都转换成了奇数长度:在每个字符的两边都插入一个特殊的符号.比如 abba 变成 #a#b#b#a#, aba变成 #a#b#a#. 为了进一步减少编码的复杂度,可以在字符串的开始加入另一个特殊字符,这样就不用特殊处理越界问题,比如 @#a#b#a#(注意,下面的代码是用C语言写 就,由于C语言规范还要求字符串末尾有一个'\0'所以正好OK,但其