/*
回文串:
输入一个字符串,求出其中最长的回文串。子串:在原串中连续出现的字符串片段。忽略标点和空格,大小写
输入字符串长度不超过5000,且占据单独一行。若有多个最长回文串,则输出起始位置最靠左的
输入:
Confuciuss say:Madam.I'm Adam.
输出:
Madam,I'm Adam
*/
/*
关键:
1printf输出到屏幕,fprintf输出到文件,sprintf输出到字符串,sprintf需要确保字符串足够大:字符个数+1(保证结束符)
2strlen求得是实际长度。声明20长度,实际"2357",那么长度是5,包含结束符,后面字符不确定
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>//isalpha函数需要用到
#define MAXSIZE 5000+1
/*
void maxEchoStr(char* str)
{
int iMaxLen = 0;
bool ok = true;
int iLen = strlen(str);
int k = 0,i,j;
while(k < iLen)
{
for(i = k,j = iLen ; i <= j ; i++,j--)
{
if(str[i] != str[j])
{
ok = false;
}
}
if(ok)
{
iMaxLen = j - i + 1;
}
}
}
*/
/*
1用fgets函数来读取一行内容,改为文件操作
2预处理设置一个字符串过滤标点,并转化成大写
3判断回文时,设置起点i,终点j,最长回文长度max,最长回文起始位置begin
4还需要设置一个数组保存起始位置,为原样输出做准备iPosArr[k] = c;
5 fgets(cBuf,MAXSIZE,fin);//char* fgets(char* buf,size_t maxsize,FIEL* stream),读取maxsize-1个字符存储到buf中,成功返回该字符串
6 if(isalpha(cBuf[c]))//#include <ctype.h>,int isalpha(int ch):字符返回非零值
7 for(i = 0 ; i < iStrLen ; i++)//回文串中间节点,
for(j = 0; i - j >= 0 && i + j < iStrLen ; j++)//对奇数进行回文串进行判断,if( 2*j + 1 > iMaxLen)//j作为回文串单边长度,因为有中间节点,所以是2*j+1,if( 2*j + 1 > iMaxLen)//j作为回文串单边长度,因为有中间节点,所以是2*j+1
for( j = 0 ; i - j >= 0 && i + j + 1 < iStrLen ; j++)//针对回文串偶数情况,if(str[i - j] != str[i + j + 1])//对相邻的情况进行判断
*/
void maxEchoStr()
{
FILE* fin;
fin = fopen("input.txt","rb");
//fout = fopen("output.txt","wb");
char cBuf[MAXSIZE];
int iPosArr[MAXSIZE];
fgets(cBuf,MAXSIZE,fin);//char* fgets(char* buf,size_t maxsize,FIEL* stream),读取maxsize-1个字符存储到buf中,成功返回该字符串
char str[MAXSIZE];
int k = 0;
int iLen = strlen(cBuf);
//去除标点符号+转换为大写
for(int c = 0 ; c < iLen ; c++)
{
if(isalpha(cBuf[c]))//#include <ctype.h>,int isalpha(int ch):字符返回非零值
{
iPosArr[k] = c;
str[k++] = toupper(cBuf[c]);
}
}
str[k] = '\0';
int iMaxLen = 0;
int iStrLen = strlen(str);
int i,j,x,y;
for(i = 0 ; i < iStrLen ; i++)//回文串中间节点
{
for(j = 0; i - j >= 0 && i + j < iStrLen ; j++)//对奇数进行回文串进行判断
{
if(str[i - j] != str[i + j])//以中间节点向两边扩展
{
break;
}
if( 2*j + 1 > iMaxLen)//j作为回文串单边长度,因为有中间节点,所以是2*j+1
{
iMaxLen = 2*j + 1;
x = iPosArr[i - j];
y = iPosArr[i + j];
}
}
for( j = 0 ; i - j >= 0 && i + j + 1 < iStrLen ; j++)//针对回文串偶数情况
{
if(str[i - j] != str[i + j + 1])//对相邻的情况进行判断
{
break;
}
if(j*2 + 2 > iMaxLen)//当j=0的时候,长度为2,所以是2*j+2
{
iMaxLen = j*2 + 2;
x = iPosArr[i - j];
y = iPosArr[i + j + 1];
}
}
}
fclose(fin);
//fclose(fout);
for(int l = x; l <= y ;l++)
{
printf("%c",cBuf[l]);
}
printf("\n");
// return echoStr;
}
void echoStr()
{
char buf[MAXSIZE],str[MAXSIZE];
FILE* fin;
fin = fopen("input.txt","rb");
fgets(buf,MAXSIZE,fin);
int iPosArr[MAXSIZE];
int x,y,iMaxLen = 0;
//预处理
int k = 0;
for(int i = 0 ; i < strlen(buf); i++)
{
if(isalpha(buf[i]))
{
iPosArr[k] = i;
str[k++] = toupper(buf[i]);
}
}
for(int p = 0 ; p < k; p++)//中间位置
{
for(int q = 0 ; p - q >= 0 && p + q <k ; q++)//检测奇数回文串
{
if(str[p -q] != str[p + q])
{
break;
}
if(2*q + 1 > iMaxLen)
{
iMaxLen = 2*q + 1;
x = iPosArr[p - q];
y = iPosArr[p + q];
}
}
for(int q = 0 ; p - q >= 0 && p + q + 1 < k ; q++)//检测偶数回文串
{
if(str[p-q] != str[p+q+1])
{
break;
}
if(2*q + 2 > iMaxLen)
{
iMaxLen = 2*q + 2;
x = iPosArr[p - q];
y = iPosArr[p + q + 1];
}
}
}
for(int c = x ; c <= y ;c++)
{
printf("%c",buf[c]);
}
printf("\n");
fclose(fin);
}
int main(int argc,char* argv[])
{
char str[MAXSIZE];
//char sBuf[MAXSIZE];
//scanf("%s",str);
maxEchoStr();
echoStr();
system("pause");
return 0;
}