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

题目链接:点击这里
在这里插入图片描述

首先解决“判断时忽略标点,输出进却要按原样”的问题?

可以用一个简单的方法:预处理。构造一个新字符串,不包含原来的标点符号,而且所有字符变成大写(顺便解决了大小写的问题)。用到的函数:

  1. i s a l p h a ( c ) isalpha(c) 用来检查c是否为字母,如果是字母,则返回1;否则返回0。
  2. i s d i g i t ( c ) isdigit(c) 用来检查c是否为数字(0~9),如果是数字,则返回1;否则返回0。
  3. t o u p p e r ( c ) toupper(c) 用来将c字符转换为大写字母,返回c对应的大写字母。
  4. t o l o w e r ( c ) tolower(c) 用来将c字符转换为小写字母,返回c对应的小写字母。

最后的问题:原样输出。

由于在求 m a x max 值时,不知道 s [ i ] s[i] s [ j ] s[j] 在原串 b u f buf 中的位置。因此,必须增加一个数组 p p ,用 p [ i ] p[i] 保存 s [ i ] s[i] b u f buf 中的位置。在预处理得到,然后在更新 m a x max 的同时把 p [ i ] p[i] p [ j ] p[j] 保存到 x x y y ,最后输出 b u f [ x ] buf[x] b u f [ y ] buf[y] 中的所有字符。

#include<iostream>
#include<algorithm>
#include<string>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<map>
#include<set>

using namespace std;
typedef long long ll;
const int MOD = 10000007;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);
const int maxn = 5010;

char buf[maxn], s[maxn];
int p[maxn];						//新串下标到原字符串下标的映射 
int dp[maxn][maxn];

int main()
{
	gets(buf);
	int lenb = strlen(buf);
	
	int len = 0;
	for(int i = 0; i < lenb; ++i)
	{
		if(isalpha(buf[i]))			//字母 
		{
			s[len] = toupper(buf[i]);
			p[len] = i;
			len++;
		}
		if(isdigit(buf[i]))	//数字 
		{
			s[len] = buf[i];
			p[len] = i;
			len++;
		}
	}
	
//	printf("%d\n", len);
//	for(int i = 0; i < len; ++i)
//		printf("%c", s[i]);
//	printf("\n"); 
	
	int start = 0;
	int maxx = 1;
	
	for(int i = 0; i < len; ++i)
	{
		dp[i][i] = 1;
		if(i<len-1&&s[i]==s[i+1])
		{
			dp[i][i+1] = 1;
			start = i;
			maxx = 2;
		}
	}
	
	for(int L = 3; L <= len; ++L)
	{
		for(int i = 0; i + L - 1 < len; ++i)
		{
			int j = i + L - 1;
			if(s[i]==s[j]&&dp[i+1][j-1]==1)
			{
				dp[i][j] = 1;
				start = i;
				maxx = L;
			}
		}
	}
	
//	printf("%d %d\n", start, maxx);
	
	for(int i = p[start]; i <= p[start+maxx-1]; ++i)
		printf("%c", buf[i]);
	return 0;
}
发布了748 篇原创文章 · 获赞 113 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/qq_42815188/article/details/104347992