Manacher算法图解

看了好久的Manacher算法,觉得还是要自己画一遍,自己把代码写一遍才能理解

下面分享一下,如果有错,希望指正

简陋版本的,但是他基本只是做到了求取最长回文字符串,严格来说它并不是Manacher’s Algorithm-马拉车算法

#include<stdio.h>   、char qdu[100050];
int manachar()
{int i;int res = 0;for (i = 1; qdu[i]; i++){int l = i;int r = i;while (qdu[i] == qdu[r + 1])r++;i = r;while (qdu[l - 1] == qdu[r + 1]) {r++;l--;}if (res < r - l + 1)res = r - l + 1;}return res;
}
int main()
{int loop;qdu[0] = '$';gets(qdu + 1);printf("%d\n", manachar());return 0;
}

Manacher’s Algorithm-马拉车算法 时间复杂度O(n)

互联网侦察微信公众号讲解,虽然文章很长,但是他讲解的十分清楚

这篇博文简单的介绍了思路

下面是核心代码,我们先看图

//Manacher算法计算过程
int MANACHER(char *st, int len)
{int mx = 0, ans = 0, po = 0;//mx即为当前计算回文串最右边字符的最大值for (int i = 1; i <= len; i++){if (mx > i)Len[i] = min(mx - i, Len[2 * po - i]);//在Len[j]和mx-i中取个小elseLen[i] = 1;//如果i>=mx,要从头开始匹配while (st[i - Len[i]] == st[i + Len[i]])Len[i]++;if (Len[i] + i > mx)//若新计算的回文串右端点位置大于mx,要更新po和mx的值{mx = Len[i] + i;po = i;}ans = max(ans, Len[i]);}return ans - 1;//返回Len[i]中的最大值-1即为原串的最长回文子串额长度 
}

首先对字符串进行预处理,处理原因是防止偶数问题(可看前面的博文)
处理后的结果进行Manacher算法。
第一个@是0,其余默认从1开始计数
首先看3 的左右都是#号所以1+1 = 2;
到了1,它可以数到6,碰到了@就不相等了,而他的回文字符串长度也是6
等到了1右边的#号,我们就可以根据对称特点,求出他和1左边的#号是同一个值(前提是这个没有超过有边界,黄色横线所示)
到这里基本就结束了
在这里插入图片描述

在这里插入图片描述

这里给出完整代码,可以自己跑一编,看看效果

#define maxn 1000010
#include <cstdio>
#include <iostream>
#include <algorithm>using namespace std;char str[maxn] = {"3212343219"};//原字符串
char tmp[maxn << 1];//转换后的字符串
int Len[maxn << 1];//转换原始串
int INIT(char *st)
{int i, len = strlen(st);tmp[0] = '@';//字符串开头增加一个特殊字符,防止越界for (i = 1; i <= 2 * len; i += 2){tmp[i] = '#';tmp[i + 1] = st[i / 2];}tmp[2 * len + 1] = '#';tmp[2 * len + 2] = '$';//字符串结尾加一个字符,防止越界tmp[2 * len + 3] = 0;return 2 * len + 1;//返回转换字符串的长度
}
//Manacher算法计算过程
int MANACHER(char *st, int len)
{int mx = 0, ans = 0, po = 0;//mx即为当前计算回文串最右边字符的最大值for (int i = 1; i <= len; i++){if (mx > i)Len[i] = min(mx - i, Len[2 * po - i]);//在Len[j]和mx-i中取个小elseLen[i] = 1;//如果i>=mx,要从头开始匹配while (st[i - Len[i]] == st[i + Len[i]])Len[i]++;if (Len[i] + i > mx)//若新计算的回文串右端点位置大于mx,要更新po和mx的值{mx = Len[i] + i;po = i;}ans = max(ans, Len[i]);}return ans - 1;//返回Len[i]中的最大值-1即为原串的最长回文子串额长度 
}int main()
{int len = INIT(str);MANACHER(tmp, len);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/382568.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flink 客户端操作命令及可视化工具

Flink提供了丰富的客户端操作来提交任务和与任务进行交互。下面主要从Flink命令行、Scala Shell、SQL Client、Restful API和 Web五个方面进行整理。 在Flink安装目录的bin目录下可以看到flink&#xff0c;start-scala-shell.sh和sql-client.sh等文件&#xff0c;这些都是客户…

ySQL挑战搭建一个简易的成绩管理系统的数据库

文章为自己搜索网上资源&#xff0c;再在这里进行整理&#xff0c;所以标注为转载 [实验步骤](https://www.shiyanlou.com/courses/reports/1347700) 总结做实验注意事项&#xff1a; 1.添加主键 2.主键和外键的关系 3.注意自增的书写添加 mysql 如何修改、添加、删除表主键…

网络之DNS协议图解

DNS是计算机域名系统 (Domain Name System) 域名系统采用类似目录树的等级结构。 域名服务器是指保存有该网络中所有主机的域名和对应IP地址&#xff0c;并具有将域名转换为IP地址功能的服务器。 域名服务器为客户机/服务器模式中的服务器方&#xff0c;它主要有两种形式&am…

C++ 谓词,

#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include <vector> #include <algorithm> using namespace std;class GreaterThen20 { public:bool operator()(int val){return val > 20;} };//一元谓词 void test01() {vector<int>v;v.push…

网络之ARP

地址解析协议&#xff0c;即ARP&#xff08;Address Resolution Protocol&#xff09;&#xff0c;是根据IP地址获取物理地址的一个TCP/IP协议。 主机发送信息时将包含目标IP地址的ARP请求广播到网络上的所有主机&#xff0c;并接收返回消息&#xff0c;以此确定目标的物理地址…

C++ 内建函数对象

STL内建了一些函数对象。分为:算数类函数对象,关系运算类函数对象&#xff0c;逻辑运算类仿函数。这些仿函数所产生的对象&#xff0c;用法和一般函数完全相同&#xff0c;当然我们还可以产生无名的临时对象来履行函数功能。使用内建函数对象&#xff0c;需要引入头文件 functi…

网络之ICMP协议

ICMP 主要功能&#xff1a; 确认IP包是否成功送达目标地址通知在发送过程当中IP包被废弃的具体原因改善网络设置等 在IP通信中如果某个IP包因为某种原因未到达目标地址&#xff0c;那么这个原因由ICMP通知。 过程&#xff08;图解TCP/IP&#xff09; ICMP类型 常见的&am…

C++ 常用算法之遍历

#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include <algorithm> #include <vector> #include <functional> using namespace std;/* 遍历算法 遍历容器元素 param beg 开始迭代器 param end 结束迭代器 param _callback 函数回调或者函数…

网络之NAT协议

由来&#xff1a; 2011年2月3日中国农历新年&#xff0c; IANA对外宣布&#xff1a;IPv4地址空间最后5个地址块已经被分配给下属的5个地区委员会。2011年4月15日&#xff0c;亚太区委员会APNIC对外宣布&#xff0c;除了个别保留地址外&#xff0c;本区域所有的IPv4地址基本耗尽…

C++ 常用查找算法

#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include <algorithm> using namespace std; #include <vector> #include <string> #include <functional> /* find算法 查找元素 param beg 容器开始迭代器 param end 容器结束迭代器 para…

CentOS7卸载并安装mysql教程

MySQL安装 先卸载其他 删除Mysql yum remove mysql mysql-server mysql-libs mysql-server;find / -name mysql 将找到的相关东西delete掉(rm -rf /var/lib/mysql)&#xff1b;rpm -qa|grep mysql(查询出来的东东yum remove掉) rm /etc/my.cnf查看是否还有mysql软件&#x…

C++ 常用排序算法

#define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; #include <algorithm> #include <vector> #include <functional> #include <ctime> /* merge算法 容器元素合并&#xff0c;并存储到另一容器中 这两个容器 必须也是…

排序稳定性的意义

首先&#xff0c;为什么会有排序算法稳定性的说法&#xff1f;只要能排好不就可以了吗&#xff1f; 看例子 第1行是数字2 记作 1 2 第2行是数字4 记作 2 4 第3行是数字2 记作 3 2 排序后的结果&#xff08;如果看不懂命令的意思&#xff0c;参照这个博客&#xff09; 那么引入…

C++ 常用拷贝和替换算法

#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include <vector> #include <algorithm> #include <iterator> using namespace std;/* copy算法 将容器内指定范围的元素拷贝到另一容器中 param beg 容器开始迭代器 param end 容器结束迭代器 p…

防火墙的基础知识入门

文章目录防火墙基于实现方式&#xff0c;防火墙的发展分为四个阶段:Linux 环境中主要的防火墙形式TCP wrappers~~详解~~ 粗解Tcp wrappers的认识它的基本过程是这样的&#xff1a;iptable攻击和防御DDOS 攻击常见的可能受到 DDOS 攻击体现的症状有&#xff1a;而常见的 DDOS 攻…

C++ 常用算数生成算法

#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include <vector> using namespace std; #include <algorithm> //不好使 #include <numeric> //好使 #include <iterator> /* accumulate算法 计算容器元素累计总和 param beg 容器开始迭代…

fork()请问下面的程序一共输出多少个“A”?多少个-?

题目&#xff1a;请问下面的程序一共输出多少个“-”&#xff1f; #include #include #include int main(void) { int i; for(i0; i<2; i){ fork(); printf("-"); } return 0; } 解析&#xff1a;一共输出8个。 首先程序一开始&am…

C++ 常用集合算法

#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include <algorithm> #include <vector> #include <iterator> using namespace std;/* set_intersection算法 求两个set集合的交集 注意:两个集合必须是有序序列 param beg1 容器1开始迭代器 par…

本能富可敌国,最后却选择拯救世界!Bram的Vim和乌干达儿童

他本能富可敌国&#xff0c;最后却选择拯救世界 在命令行界面输入vim会出现一堆文件&#xff0c;但是一直有这么一句话 Help poor children in Uganda! “帮助可怜的乌干达儿童” 查询了一下这里面相关的历史背景和知识 在Vim许可证文件结束后的部分翻译 &#xff0d;如果…

linux 常用命令01

/bin/bash 就是linux默认的shell ls命令 ls -a 显示所有文件 包含隐藏文件 ls -R 递归显示子目录 ls -l 显示详细信息 ls -lrt 按照时间排序&#xff0c;显示文件信息 配合通配符使用 ls *.c *匹配任意多个字符 ls xx.? 匹配任意一个字符 cd 命令 cd - 为切换到上次目录 cd 回…