问题 A: 【字符串】最长回文子串

问题 A: 【字符串】最长回文子串
[命题人 : 外部导入]
时间限制 : 1.000 sec 内存限制 : 128 MB

题目描述
输入一个字符串,求出其中最长的回文子串。子串的含义是:在原串中连续出现的字符串片段。回文的含义是:正着看和倒着看相同。如abba和yyxyy。在判断回文时,应该忽略所有标点符号和空格,且忽略大小写,但输出应保持原样(在回文串的首部和尾部不要输出多余字符)。输入字符串长度不超过5000,且占据单独的一行。应该输出最长的回文串,如果有多个,输出起始位置最靠左的。

输入
一行字符串,字符串长度不超过5000。

输出
字符串中的最长回文子串。

样例输入 Copy
Confuciuss say:Madam,I’m Adam.
样例输出 Copy
Madam,I’m Adam
提示
**样例说明:**Madam,I’m Adam去掉空格、逗号、单引号、忽略大小写为MADAMIMADAM,是回文。

一道不怎么用到脑力的题目,卡了半小时,回文串的细节就直接用回文串的模板就行,他的状态公式即是判断 两个字符是否相等,相等时向内左右各收缩一格,判断dp的状态,是则1,否则0;注意判断的过程需要按3 4 5不断的间隔,原因是:举个例子,从0 1 2 3 4 下标看,04的比较需要13,所以间隔为4的需要间隔为3 的提前铺垫。dp的预处理初始化要注意dp[i][i]dp[i][i+1]为1或0.
下面讲讲此题,把数字和字母的字符用一个新的数字a保持,记得用hasha数组保存这个字符对应于原数组的位置下标,然后用结构体对象R保存每次遍历得到的最长串的位于a数组的下标。
题目不难,只要掌握了基本的回文串,套个框框下去就轻松解决!

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
char a[5000];
char a_tmp[5000];
int dp[5000][5000];
int hasha[5000];//记录原始下标  a对应原来a_tmp的下标 
struct record {
	int x;
	int y;
	int changdu;
} R;
char Toup(char aa) {
	if(isdigit(aa)) return aa;
	if(aa >= 'a'&&aa <= 'z') {
		return aa-32;
	} else {
		return aa;
	}
}
int main() {
	cin.getline(a_tmp,5000);
	int lena_tmp = strlen(a_tmp);
	int num = 0;
	for(int i = 0; i < lena_tmp; i++) {
		char temp = a_tmp[i];
		if(isalpha(temp)||isdigit(temp)) {
			hasha[num] = i;//记录原始下标
			//千万不可以把它改为都是大写,之后无法复原到原来对应的大小写的原数组位置!!
			//遍历判断时进行toupper就可以了
			a[num++] = temp;
		}
	}
	a[num] = '\0';
	int lena = strlen(a);
	memset(dp,0,sizeof(dp));
	int ans = 1;
	R.x = 0;
	R.y = 0;
	R.changdu = 1;
	//a是带有大小写的  判断的时候注意
	char tempi,tempj;
	for(int i = 0 ; i < lena; i++) {
		dp[i][i] = 1;

		tempi = Toup(a[i]);//注意数字
		tempj = Toup(a[i+1]);

		if(tempi==tempj&&i<lena-1) {
			dp[i][i+1] = 1;
			ans = 2;
			R.x = i;
			R.y = i + 1;
			R.changdu = 2;
		}
	}
	//a是带有大小写的  判断的时候注意
	for(int L = 3; L <= lena; L++) {
		for(int i = 0; i + L - 1 < lena; i++) {
			int j = i + L - 1;
			tempi = Toup(a[i]);//注意数字
			tempj = Toup(a[j]);
			if(tempi==tempj&&dp[i + 1][j - 1]==1) {
				dp[i][j] = 1;
				ans = L;
				if(L>R.changdu) {
					R.x = i;
					R.y = j;
					R.changdu = L;
				}
			}
		}
	}
//	for(int i = 0; i <= lena - 1; i++) {
//		printf("%c",a[i]);
//	}
//	printf("%d",ans);
//	for(int i = R.x; i <= R.y; i++) {
//		printf("%c",a[i]);
//	}
//	printf("\n%d\n",ans);
		//通过hasha的下标  即原始串的位置, 
	int start = hasha[R.x];
	int end = hasha[R.y];
	for(int i = start; i <= end; i++){
		printf("%c",a_tmp[i]);
	}
	return 0;
}

发布了78 篇原创文章 · 获赞 3 · 访问量 6581

猜你喜欢

转载自blog.csdn.net/weixin_38023259/article/details/104925260