马拉车的定义

马拉车本质是对中心扩展法(暴力算法)的优化。

马拉车是干什么的

Manacher算法帮助我们在给定的字符串中找到最长的回文子串

为了简单起见,我们先只处理有奇数个字符的字符串,关于偶数个字符的字符串,在文章最后会给出解法。我们的处理思路和暴力算法基本一致,那就是从左到右一个字符一个字符来处理这个字符串,寻找以当前处理的字符为中心的最长回文串,假设字符串的长度是N,那我们就在寻找到的N个最长回文串中取最长的就是答案了。

符号说明

我们约定,c是我们处理当前字符时,已经找到的右边界最大的回文字符串的中心。l和r分别是这个最长的回文字符串的左界和右界,也就是最左边的字符索引和最右边的字符索引。现在,我们举个例子来理解c、l和r。

例子:“abacabacabb”



当从左到右一个字符一个字符计算时,我们用i表示当前正在处理的字符的索引,当i在索引1时,最长的回文字符串是 "aba"(长度=3)。

当i在索引5时,如下图所示:



最长的回文字符串的答案是9,c、l、r的值如图中所示。

不难看出,c所代表的最长回文字符串

现在我们知道了c、l和r表示什么,为了下面算法的讲解更加自然,我们需要了解一个概念:镜像索引。

对于以c为中心的任何一个回文字符串来说 索引j关于c的镜像是j',如下图所示:



观察上图,不难得出下面的计算公式:

c - j = j' - c

此时,j的镜像j':

j' = (2 * c) - j

模板

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn = 3e5 + 5;
char s[maxn], t[maxn];
int p[maxn]; int main() {
while (~scanf("%s", s)) {
int l = strlen(s), len = 0;
t[len++] = '$'; // 在字符串开头和结尾都添加一个特殊字符(如'$',
// 注意不要相同),使后续计算可以避免判断越界
t[len++] = '#';
for (int i = 0; i < l; ++i) {
t[len++] = s[i];
t[len++] = '#';
}
t[len] = '&'; int center = 0, max_right = 0;
for (int i = 1; i < len; ++i) {
int i_mirror = 2 * center - i;
if (max_right >
i) { // 在最右边界的覆盖范围内, 就利用回文串特征计算长度
p[i] = min(max_right - i,
p[i_mirror]); // 使用min()是为了防止超出最右边界
} else {
p[i] = 0;
}
while (t[i - 1 - p[i]] == t[i + 1 + p[i]])
++p[i]; if (i + p[i] > max_right) { // 更新右边界的回文串中心
center = i;
max_right = i + p[i];
}
} int max_len = 0;
// int pos = 0; //记录最长回文子串中心的位置
for (int i = 1; i < len; ++i)
if (max_len < p[i]) {
max_len = p[i];
// pos = i;
}
printf("%d\n", max_len); //最长回文串的起始位置为: (pos - max_len) / 2
}
return 0;
}

manacher(马拉车)算法C++详解的更多相关文章

  1. Manacher(马拉车)算法(jekyll迁移)

    layout: post title: Manacher(马拉车)算法 date: 2019-09-07 author: xiepl1997 cover: 'assets/img/manacher.p ...

  2. 一致性算法RAFT详解

    原帖地址:http://www.solinx.co/archives/415?utm_source=tuicool&utm_medium=referral一致性算法Raft详解背景 熟悉或了解 ...

  3. 各大公司广泛使用的在线学习算法FTRL详解

    各大公司广泛使用的在线学习算法FTRL详解 现在做在线学习和CTR常常会用到逻辑回归( Logistic Regression),而传统的批量(batch)算法无法有效地处理超大规模的数据集和在线数据 ...

  4. 转】Mahout推荐算法API详解

    原博文出自于: http://blog.fens.me/mahout-recommendation-api/ 感谢! Posted: Oct 21, 2013 Tags: itemCFknnMahou ...

  5. MD5算法步骤详解

    转自MD5算法步骤详解 之前要写一个MD5程序,但是从网络上看到的资料基本上一样,只是讲了一个大概.经过我自己的实践,我决定写一个心得,给需要实现MD5,但又不要求很高深的编程知识的童鞋参考.不多说了 ...

  6. [转]Mahout推荐算法API详解

    Mahout推荐算法API详解 Hadoop家族系列文章,主要介绍Hadoop家族产品,常用的项目包括Hadoop, Hive, Pig, HBase, Sqoop, Mahout, Zookeepe ...

  7. 2. EM算法-原理详解

    1. EM算法-数学基础 2. EM算法-原理详解 3. EM算法-高斯混合模型GMM 4. EM算法-高斯混合模型GMM详细代码实现 5. EM算法-高斯混合模型GMM+Lasso 1. 前言 概率 ...

  8. [置顶] Isolation Forest算法实现详解

    本文算法完整实现源码已开源至本人的GitHub(如果对你有帮助,请给一个 star ),参看其中的 iforest 包下的 IForest 和 ITree 两个类: https://github.co ...

  9. [置顶] Isolation Forest算法原理详解

    本文只介绍原论文中的 Isolation Forest 孤立点检测算法的原理,实际的代码实现详解请参照我的另一篇博客:Isolation Forest算法实现详解. 或者读者可以到我的GitHub上去 ...

  10. Isolation Forest算法实现详解

    本文介绍的 Isolation Forest 算法原理请参看我的博客:Isolation Forest异常检测算法原理详解,本文中我们只介绍详细的代码实现过程. 1.ITree的设计与实现 首先,我们 ...

随机推荐

  1. 2022-08-18:每一个序列都是[a,b]的形式,a < b 序列连接的方式为,前一个序列的b,要等于后一个序列的a 比如 : [3, 7]、[7, 13]、[13, 26]这三个序列就可以依次连

    2022-08-18:每一个序列都是[a,b]的形式,a < b 序列连接的方式为,前一个序列的b,要等于后一个序列的a 比如 : [3, 7].[7, 13].[13, 26]这三个序列就可以 ...

  2. golang版本sdl2显示窗体

    golang版本sdl2显示窗体 go用syscall调用sdl2,在win10 x64上没问题,其他系统不敢保证. 见地址 package main import ( "fmt" ...

  3. 2021-05-20:给定一个数组arr, 返回如果排序之后,相邻两数的最大差值。要求:时间复杂度O(N) 。

    2021-05-20:给定一个数组arr, 返回如果排序之后,相邻两数的最大差值.要求:时间复杂度O(N) . 福大大 答案2021-05-20: 假设答案法.N个数,根据最大值和最小值的范围等分成N ...

  4. WPF入门教程系列二十四——DataGrid使用示例(1)

    WPF入门教程系列二--Application介绍 WPF入门教程系列三--Application介绍(续) WPF入门教程系列四--Dispatcher介绍 WPF入门教程系列五--Window 介 ...

  5. vue全家桶进阶之路43:Vue3 Element Plus el-form表单组件

    在 Element Plus 中,el-form 是一个表单组件,用于创建表单以便用户填写和提交数据.它提供了许多内置的验证规则和验证方法,使表单验证更加容易. 使用 el-form 组件,您可以将表 ...

  6. defer()排除某些字段

    defer()排除某些字段 不显示nickname,age两列的数据 Student.objects.all().defer('nickname','age')

  7. Kafka 杂谈

    开始之前 首先,此篇文章会有很多地方会和 RocketMQ 比较,不太熟悉 RocketMQ 可以去看看我之前写的RocketMQ基础概念剖析&源码解析,先有个大概的印象,可能会帮助你更好的理 ...

  8. Java(instanceof和类型转换)

    1.instanceof和类型转换 instanceof 引用类型比较,判断一个对象是什么类型 public static void main(String[] args) { // Object & ...

  9. C++程序开发技巧

    引言 类(class)的使用分为两种--基于对象(object Based)和面向对象(object oriented) 基于对象是指,程序设计中单一的类,和其他类没有任何关系 单一的类又分为:不带指 ...

  10. 自然语言处理 Paddle NLP - 文本语义相似度计算(ERNIE-Gram)

    基于预训练模型 ERNIE-Gram 实现语义匹配 1. 背景介绍 文本语义匹配任务,简单来说就是给定两段文本,让模型来判断两段文本是不是语义相似. 在本案例中以权威的语义匹配数据集 LCQMC 为例 ...