【我的板子】manacher

问题描述

给定一个字符串s,找出所有(i,j)使得s[i……j]为回文串。(回文串就是正看倒看都一样的串)

一、朴素算法

分该回文串是奇数串还是偶数串,遍历中心位向两边延伸

vector<int> d1(n), d2(n);
for (int i = 0; i < n; i++) {
  d1[i] = 1;
  while (0 <= i - d1[i] && i + d1[i] < n && s[i - d1[i]] == s[i + d1[i]]) {
    d1[i]++;
  }

  d2[i] = 0;
  while (0 <= i - d2[i] - 1 && i + d2[i] < n &&
         s[i - d2[i] - 1] == s[i + d2[i]]) {
    d2[i]++;
  }
}

二、manacher算法

z函数思想一样
,代码也基本一样,思想就是通过利用之前已求出来的值来计算当前值

分奇偶处理时

奇回文字符串

vector<int> d1(n);
for (int i = 0, l = 0, r = -1; i < n; i++) {
  int k = (i > r) ? 1 : min(d1[l + r - i], r - i);
  while (0 <= i - k && i + k < n && s[i - k] == s[i + k]) {
    k++;
  }
  d1[i] = k--;
  if (i + k > r) {
    l = i - k;
    r = i + k;
  }
}

偶回文字符串 (假定和第i个相等的字符在i-1的位置)

vector<int> d2(n);
for (int i = 0, l = 0, r = -1; i < n; i++) {
  int k = (i > r) ? 0 : min(d2[l + r - i + 1], r - i + 1);
  while (0 <= i - k - 1 && i + k < n && s[i - k - 1] == s[i + k]) {
    k++;
  }
  d2[i] = k--;
  if (i + k > r) {
    l = i - k - 1;
    r = i + k;
  }
}

优化算法

我们先做一个预处理,将原字符串每个间隙都用’#'隔开,这样的话,我们就不用分奇偶两种情况讨论了。比如
原串:a b a b a b c
先串:# a # b # a # b # a # b # c #

为什么不用分奇偶讨论了呢

设m是原串回文串的长度
当m时奇数时,比如是a b a,这时现回文字符串# a # b # a #的长度要比原回文字符串的长度大m+1(多了#的个数),所以现回文字符串的长度是2*m+1,是奇数。
当m时偶数时,比如是a b b a,这时现回文字符串# a # b # b a #的长度还是比原回文字符串的长度大m+1(多了#的个数),所以现回文字符串的长度是2*m+1,还是奇数。
总之,现回文字符串的长度会一直是奇数,可以直接按分奇偶处理时的奇数法处理


//预处理
stirng s,str;cin>>s;
int len=s.size();
for(int i=0;i<=2*len;++i)
{	if(i&1)str[i]=s[i/2];
	else str[i]='#';
}
### 如何将Arduino连接到自定义板子 #### 硬件准备 为了实现Arduino与自定义板之间的通信,需准备好相应的硬件组件。通常情况下,这包括但不限于Arduino开发板本身、目标自定义板以及用于两者间信号传输的数据线或排针等配件。 #### 接口匹配 确保所选Arduino型号具备足够的I/O接口来满足自定义板的需求。例如,如果自定义板需要SPI通讯,则应确认Arduino拥有对应的MOSI, MISO, SCK引脚;对于IIC/SPI OLED显示屏而言,除了上述提到的GPIO外还需要额外配置SCL和SDA管脚[^1]。 #### 驱动安装 针对某些特殊功能模块(比如带有SSD1306控制器的小型OLED显示器),可能还需事先加载专用库文件至Arduino集成环境内以便顺利调用API完成初始化设置等工作流程。这类操作可通过访问官方文档获取指导说明并按照指示逐步实施即可。 #### 初始化串行通信 当涉及到通过UART总线与其他设备交换数据时,应当利用`Serial.begin()`函数指定波特率参数启动相应通道。值得注意的是,在多串口支持平台如Arduino Mega上存在多个实例可供选择,具体形式为`SerialX.begin(speed)`其中X代表编号而speed则指代实际速率值[^2]。 #### Arduino IDE界面简介 Arduino IDE提供了直观易懂的操作面板辅助开发者高效开展编程工作。其布局结构清晰合理,涵盖了菜单栏、工具条、编辑窗口及状态提示等多个重要组成部分。特别是位于顶部的任务快捷按钮群组——它们分别承担着验证代码合法性、部署固件映像、创建新工程档案等功能角色,极大地方便了用户的日常使用体验[^3]。 ```cpp // 示例:建立基本串行连接 void setup() { Serial.begin(9600); // 设置默认串口号及其传输速度 } void loop() { if (Serial.available()) { // 检查是否有待处理的信息包到达缓冲区 char receivedChar = Serial.read(); // 获取单字节字符流片段 Serial.println(receivedChar); // 将接收内容回显给发送方查看反馈效果 } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值