zoukankan      html  css  js  c++  java
  • L2-008 最长对称子串 (回文子串 / DP)

    L2-008 最长对称子串 (25分)

    对给定的字符串,本题要求你输出最长对称子串的长度。例如,给定Is PAT&TAP symmetric?,最长对称子串为s PAT&TAP s,于是你应该输出11。

    输入格式:

    输入在一行中给出长度不超过1000的非空字符串。

    输出格式:

    在一行中输出最长对称子串的长度。

    输入样例:

    Is PAT&TAP symmetric?
    

    输出样例:

    11
    

    思路一

    由于字符串长仅1000,可以选择直接暴力找

    思路二

    套一下马拉车算法的模板即可

    算法讲解:Here

    #include <algorithm>
    #include <cstring>
    #include <iostream>
    using namespace std;
    string s;
    char s_new[4000];
    int p[5000];
    int Init() {
        int len = s.length();
        s_new[0] = '$';
        s_new[1] = '#';
        int j = 2;
        for (int i = 0; i < len; i++) {
            s_new[j++] = s[i];
            s_new[j++] = '#';
        }
        s_new[j] = '';  // 别忘了哦
        return j;         // 返回 s_new 的长度
    }
    
    int Manacher() {
        int len = Init();  // 取得新字符串长度并完成向 s_new 的转换
        int max_len = -1;  // 最长回文长度
        int id;
        int mx = 0;
        for (int i = 1; i < len; i++) {
            if (i < mx)
                p[i] = min(p[2 * id - i],
                           mx - i);  // 需搞清楚上面那张图含义, mx 和 2*id-i 的含义
            else
                p[i] = 1;
    
            while (s_new[i - p[i]] ==
                   s_new[i + p[i]])  // 不需边界判断,因为左有'$',右有''
                p[i]++;
    
            // 我们每走一步 i,都要和 mx 比较,我们希望 mx
            // 尽可能的远,这样才能更有机会执行 if (i < mx)这句代码,从而提高效率
            if (mx < i + p[i]) {
                id = i;
                mx = i + p[i];
            }
            max_len = max(max_len, p[i] - 1);
        }
        return max_len;
    }
    
    int main() {
        getline(cin, s);
        printf("%d
    ", Manacher());
        return 0;
    }
    

    思路三

    没想到可以使用DP做,思路来自网络

    动态规划:

    分析:有两种可能,⼀种是回⽂字符串的⻓度为奇数,⼀种是偶数的情况。i为字符串当前字符的下 标。

    ​ 当回⽂字串为奇数的时候,j表示i-j与i+j构成的回⽂字串⻓度;当回⽂字串⻓度为偶数的时候,j表示

    ​ i+1左边j个字符⼀直到i右边j个字符的回⽂字串⻓度~

    ​ ⽤maxvalue保存遍历结果得到的最⼤值并且输出~

    #include <iostream>
    using namespace std;
    int main() {
        string s;
        getline(cin, s);
        int maxvalue = 0, temp;
        int len = s.length();
        for (int i = 0; i < len; i++) {
            temp = 1;
            for (int j = 1; j < len; j++) {
                if (i - j < 0 || i + j >= len || s[i - j] != s[i + j])
                    break;
                temp += 2;
            }
            maxvalue = temp > maxvalue ? temp : maxvalue;
            temp = 0;
            for (int j = 1; j < len; j++) {
                if (i - j + 1 < 0 || i + j >= len || s[i - j + 1] != s[i + j])
                    break;
                temp += 2;
            }
            maxvalue = temp > maxvalue ? temp : maxvalue;
        }
        cout << maxvalue;
        return 0;
    }
    
  • 相关阅读:
    数组04 零基础入门学习C语言26
    寄存器(CPU工作原理)06 零基础入门学习汇编语言11
    数组04 零基础入门学习C语言26
    数组06 零基础入门学习C语言28
    数组05 零基础入门学习C语言27
    寄存器(CPU工作原理)05 零基础入门学习汇编语言10
    数组06 零基础入门学习C语言28
    现宣布Windows Azure中SQL数据同步的增强功能
    Windows Azure媒体服务使得伦敦奥运会的云端传输成为可能
    介绍Windows Azure移动服务:用于您连接的客户端应用程序的后端
  • 原文地址:https://www.cnblogs.com/RioTian/p/14044425.html
Copyright © 2011-2022 走看看