题目描述:
输入一个字符串,求出其中最长的回文。(回文:正着看和倒着看相同,如abba和yyxyy)。在判断时,应该忽略所有标点符号和空格,且忽略大小写,但输出应保持原样。输入字符串的长度不超过5000,且占据单独的一行。ying'g输出最长的回文串,如果有多个,输出起始位置最左边的。
样例输入:Confuciuss say: Madam,I'm Adam.
样例输出:Madam,I'm Adam
我们可以用fgets函数来得到输入,格式为fgets(buf,max_size,stdin),它将读取完整的一行放入数组buf中。我们应当保证buf足够存放一行的内容。
因为字符串有很多标点,空格等,我们先将字符串预处理:构造一个新的字符串,不包含原来的标点符号,而且将所有字符变成大写。
1 n = strlen(buf); 2 m = 0; 3 for(i = 0;i<n;i++) 4 if(isalpha(buf[i])) s[m++] = toupper(buf[i]);
1.枚举法
思路:枚举串的起点和终点,然后判断它是否是回文串。
1 //伪代码 2 int max = 0; 3 4 for(i = 0;i<m;i++) 5 6 for(j =i;j<m;j++) 7 8 if(s[i...j]是回文串&&j-i+1>max) max = j-i+1;
判断s[i...j]是否为回文串的方法:
1 int ok = 1; 2 3 for(k=i;k<=j;k++) 4 5 if(s[k]!=s[i+j-k]) ok = 0; // s[k]与s[i+j-k]为“对称位置”
或者还可以这样判断:
1 int ok = 1; 2 // 判断回文 3 int t1, t2; 4 for (t1 = i, t2 = j; t1 < t2; t1++, t2--) { 5 if (s[t1] != s[t2]) 6 ok = 0; 7 }
1 #include<iostream> 2 #include<cctype> 3 #include<string> 4 using namespace std; 5 6 const int MAX = 5010; 7 char buf[MAX], s[MAX]; 8 9 int main() 10 { 11 int n, m = 0, max = 0; 12 int i, j, k; 13 int start; 14 fgets(buf, sizeof(s), stdin); 15 n = strlen(buf); 16 for (i = 0; i < n; i++) 17 if (isalpha(buf[i])) s[m++] = toupper(buf[i]); 18 for (i = 0; i < m; i++) { 19 for (j = i; j < m; j++) { 20 int ok = 1; 21 // 判断回文 22 int t1, t2; 23 for (t1 = i, t2 = j; t1 < t2; t1++, t2--) { 24 if (s[t1] != s[t2]) 25 ok = 0; 26 } 27 if (ok&&j - i + 1 > max) { 28 max = j - i + 1; 29 start = i; 30 } 31 } 32 } 33 for (int x = start; x < start+max; x++) { 34 cout << s[x]; 35 } 36 cout << "最大回文字串的长度为" << max << endl; 37 system("pause"); 38 return 0; 39 }
为了输出子串在字符串中原本的模样,需要用一个数组记录,p[i]保存s[i]在buf中的位置。
最终版本为:
1 #include<iostream> 2 #include<string> 3 #include<cctype> 4 using namespace std; 5 6 char buf[100]; 7 char str[100]; 8 int pos[100]; 9 int main() 10 { 11 int m = 0; 12 int max = 0; 13 int start; 14 int x, y; 15 fgets(buf, sizeof(str), stdin); 16 int n = strlen(buf); 17 for (int i = 0; i < n; ++i) { 18 if (isalpha(buf[i])) { 19 pos[m] = i; 20 str[m++] = toupper(buf[i]); 21 } 22 } 23 24 for (int i = 0; i < m; i++) { 25 for (int j = 0; i - j >= 0 && i + j < m; j++) // 处理字符串为奇数时的情况 26 { 27 if (str[i - j] != str[i + j])break; 28 if (j * 2 + 1 > max) { 29 max = j * 2 + 1; 30 x = pos[i - j]; 31 y = pos[i + j]; 32 } 33 } 34 35 for (int j = 0; i - j >= 0 && i + j + 1 < m; j++) // 处理字符串为偶数时的情况 36 { 37 if (str[i - j] != str[i + j + 1])break; 38 if (j * 2 + 2 > max) { 39 max = j * 2 + 2; 40 x = pos[i - j]; 41 y = pos[i + j + 1]; 42 } 43 } 44 } 45 for (int i = x; i <= y; i++) 46 cout << buf[i]; 47 cout << endl; 48 49 cout << endl; 50 cout << "最大回文串的长度为" << max << endl; 51 system("pause"); 52 }