• 马拉车算法【Manachar】


    马拉车算法【Manachar】
    [优秀的算法总结](https://blog.csdn.net/dyx404514/article/details/42061017?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162657705716780274134211%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=162657705716780274134211&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-42061017.first_rank_v2_pc_rank_v29&utm_term=manacher%E7%AE%97%E6%B3%95&spm=1018.2226.3001.4187)
    Manachar算法:

    > 因为上面这一片博客已经将Manachar讲的很清楚了,我就不再多做赘述,直接说下算法流程以及结论。
    >
    > 1.预处理:将字符串间隔插入一个不会在原串出现的字符,可以给开始字符记为$结尾字符记为^
    >
    > 2. 变量所携带的信息
    >
    > 1. p[i]表示以当前字符i开始,最长的回文子串的半径是多少。注意,P[i]所拥有的回文串都是奇数串。
    > 2. mx表示回文串最远可以到达那里,
    > 3. resLen,表示P[i]的最大值,也就是我们需要求的最长回文子串的长度,注意,p[i]所表示的值,总是会比我们真实的原串的回文子串的长度多1。
    > 4. resCentre表示最长回文子串的中间位置,对应原串位置为整除2,不用考虑是否下取整,因为原串的每个字符在对应的扩展后的串中,都是在偶数下标下的。
    >
    > 3. `p[i] = mx > i ? min(p[id * 2 - i], mx - i) : 1`
    >
    > p[i]没扩展的时候,只能在mx内取
    >
    > while(b[i - p[i]] == b[i + p[i]]) p[i] ++;
    >
    > 扩展当前i的p数组
    >
    > 更新mx:只要当前p更新了,一定mx也更新了,毕竟mx是我们的边界
    >
    > 4. 然后返回所需信息

    模板:string写的,在字符长度大的情况下,可能会超时,建议,写成char形式。在下面也有
    ```cpp
    #include <bits/stdc++.h>

    using namespace std;

    string Mannacher(string s)
    {
    //插入“#”
    string t = "%#";
    for (int i = 0; i < s.size(); i ++ )
    {
    t += s[i];
    t += '#';
    }

    vector<int> p(t.size(), 0);
    //mx表示某个回文串延展在最右端半径下标,id表示这个回文子串最中间位置下标
    //resLen表示在对应C中最大回文子串的半径,resCentre表示最大回文串的中间位置
    int mx = 0, id = 0, resLen = 0, resCentre = 0;

    //建立p数组
    for (int i = 1; i < t.size(); i ++ )
    {
    p[i] = mx > i ? min(p[2 * id - i], mx - i) : 1;

    //遇到阿森纳中特殊情况,需要利用中心扩展法
    while (t[i + p[i]] == t[i - p[i]]) p[i] ++;

    //半径下标i + p[i]超过边界mx,需要更新
    if (mx < i + p[i])
    {
    mx = i + p[i];
    id = i;
    }

    //更新最大回文子串的信息,半径及中心位置
    if (resLen < p[i])
    {
    resLen = p[i];
    resCentre = i;
    }
    }

    return s.substr((resCentre - resLen) / 2, resLen - 1);
    }

    int main()
    {
    string s;
    while (cin >> s)
    {
    cout << Mannacher(s).size() << endl;
    }

    return 0;
    }

    ```
    题目:

    [AcWing 3188. manacher算法]([3188. manacher算法 - AcWing题库](https://www.acwing.com/problem/content/3190/))

    ```cpp
    #include <bits/stdc++.h>
    using namespace std;
    const int N = 20000005;
    char a[N], b[N];
    int p[N];
    int n;
    void init()
    {
    n = strlen(a);
    int k = 0;
    b[k ++ ] = '$', b[k ++ ] = '#';
    for (int i = 0; i < n; i ++ ) b[k ++ ] = a[i], b[k ++ ] = '#';
    b[k ++ ] = '^';
    n = k;
    cout << b << endl;
    }
    int Manachar()
    {
    int mx = 0, id = 0, resLen = 0, resCentre = 0;
    for (int i = 1; i < n; i ++ )
    {
    p[i] = mx > i ? min(p[id * 2 - i], mx - i) : 1;
    while (b[i - p[i]] == b[i + p[i]]) p[i] ++;
    if (mx < i + p[i])
    {
    mx = i + p[i];
    id = i;
    }
    if (resLen < p[i])
    {
    resLen = p[i];
    resCentre = i;
    }
    }
    return resLen - 1;
    }
    int main()
    {
    cin >> a;
    init();
    cout << Manachar() << endl;
    return 0;
    }
    ```

  • 相关阅读:
    halcon三种模板匹配方法
    线阵相机与面阵相机的区别
    完整性检测
    halcon读取一张照片,并转化为灰度图像
    halcon车牌的识别
    HALCON学习之条形码实时扫描
    开关引脚测量
    ip sensor芯片级解决方案
    ip camera芯片级解决方案
    Parallel For Bug in static constructor
  • 原文地址:https://www.cnblogs.com/Iamcookieandyou/p/15026919.html
Copyright © 2020-2023  润新知