zoukankan      html  css  js  c++  java
  • 最大回文字串

    题目描述:
      输入一个字符串,求出其中最长的回文。(回文:正着看和倒着看相同,如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 }
  • 相关阅读:
    bzoj1015星球大战(并查集+离线)
    bzoj1085骑士精神(搜索)
    bzoj1051受欢迎的牛(Tarjan)
    左偏树学习
    hdu1512 Monkey King(并查集,左偏堆)
    左偏树(模板)
    PAT (Basic Level) Practice (中文) 1079 延迟的回文数 (20分) (大数加法)
    PAT (Basic Level) Practice (中文) 1078 字符串压缩与解压 (20分) (字符转数字——栈存放)
    PAT (Basic Level) Practice (中文) 1077 互评成绩计算 (20分) (四舍五入保留整数)
    PAT (Basic Level) Practice (中文) 1076 Wifi密码 (15分)
  • 原文地址:https://www.cnblogs.com/ll-10/p/9601692.html
Copyright © 2011-2022 走看看