• 【内功】基础算法——字符串


    [1] Manacher 

    求一个字符串中的最长回文子串。

    讲解直接放ppt,复习能回忆起来就行。

     

     1 #include <iostream>
     2 #include <string>
     3 #include <vector>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 string manacher(string& s) {
     8     vector<int> p(s.size(), 0);
     9     int mx = 0, dx = 0;
    10     for (auto i = 1; i < s.size(); ++i) {
    11         if (mx > i) {
    12             p[i] = min( p[2*dx-i] , (int)mx-i);
    13         } else {
    14             p[i] = 1;
    15         }
    16         while (s[i+p[i]] == s[i-p[i]]) {
    17             p[i]++;
    18         }
    19         if (p[i] + i > mx) {
    20             mx = p[i] + i;
    21             dx = i;
    22         }
    23     }
    24     int index = -1, max_len = -1;
    25     for (auto i = 1; i < s.size(); ++i) {
    26         if (p[i] > max_len) {
    27             index = i;
    28             max_len = p[i];
    29         }
    30     }
    31     max_len--; // P[i]-1正好是原字符串中回文串的总长度
    32     int start = index - max_len;
    33     int end = index + max_len;
    34     string ans = "";
    35     for (int i = start; i <= end; ++i) {
    36         if (s[i] != '#') {
    37             ans += s[i];
    38         }
    39     }
    40 
    41     cout << "s = ";
    42     for (int i = 0; i < s.size(); ++i) {
    43         cout << s[i] << " ";
    44     }
    45     cout << endl;
    46     cout << "p = ";
    47     for (int i = 0; i < s.size(); ++i) {
    48         cout << p[i] << " ";
    49     }
    50     cout << endl;
    51 
    52     return ans;
    53 }
    54 
    55 int main() {
    56     string s;
    57     cin >> s;
    58     string tmp = "$#";
    59     for(int i = 0; i < s.size(); ++i) {
    60         tmp += s[i];
    61         tmp += "#";
    62     }
    63     cout << tmp << endl;
    64     string palindrome = manacher(tmp);
    65     cout << palindrome << endl;
    66     return 0;
    67 }
    manacher

    [2] KMP

    判断在字符串 s 中查找 模式串 p,返回 p 在 s 中第一个位置下标。

    算法讲解我看了 July 的 《编程之法》4.4 字符串的查找。

    https://blog.csdn.net/v_JULY_v/article/details/7041827

    他讲了一个要点,就是next数组的含义,next 数组就是只要将各个前缀和后缀的公共元素的最大长度值右移一位,并且把初值赋值成 -1 即可。

    基础题目练习:

    (1) leetcode 28 strstr (直接裸的kmp)

     1 class Solution {
     2 public:
     3     int strStr(string haystack, string needle) {
     4         return kmp(haystack, needle);
     5     }
     6     int kmp(string& s, string& p) {
     7         const int n = s.size(), m = p.size();
     8         if (m == 0) {return 0;} //p empty
     9         vector<int> next = getNext(p);
    10         int i = 0, j = 0;
    11         while (i < n && j < m) {
    12             if (j == -1 || s[i] == p[j]) {
    13                 ++i, ++j;
    14             } else {
    15                 j = next[j];
    16             }
    17         }
    18         if (j == m) {
    19             return i - j;
    20         }
    21         return -1;
    22     }
    23     vector<int> getNext(string& p) {
    24         const int n = p.size();
    25         vector<int> next(n, 0);
    26         next[0] = -1;
    27         int j = 0, k = -1;
    28         while (j < n - 1) {
    29             if (k == -1 || p[j] == p[k]) {
    30                 ++k, ++j;
    31                 next[j] = p[j] == p[k] ? next[k] : k;
    32             } else {
    33                 k = next[k];
    34             }
    35         }
    36         return next;
    37     }
    38 };
    View Code

    (2) https://hihocoder.com/problemset/problem/1015

    题意是找出 S 串中出现模式串 P 的个数。

    【3】求第一个比 N 大的回文数。(字符串处理 + 可以当作数学)

    【4】trie 树

  • 相关阅读:
    算法竞赛进阶指南--lowbit运算,找到二进制下所有是1的位
    linux
    conda配置安装pytorch
    anaconda的安装及使用
    python操作mysql
    python生成文字云
    决策树基本原理
    Ubuntu截图软件
    ubuntu安装teamviewer
    k-最近邻算法基本原理
  • 原文地址:https://www.cnblogs.com/zhangwanying/p/6472455.html
Copyright © 2020-2023  润新知