算法竞赛——字符串算法

前言

本文对算法竞赛中可能涉及字符串算法做一个功能说明。

1.Trie(字典树)

算法功能:判断一个字符串在模式串中出现的次数

例题1:维护一个字符串集合,支持两种操作:
I x 向集合中插入一个字符串 x;
Q x 询问一个字符串在集合中出现了多少次。

2.KMP

算法功能:线性复杂度求匹配串在模式串出现的位置

例题1:给定一个模式串 S,以及一个模板串 P,所有字符串中只包含大小写英文字母以及阿拉伯数字。模板串 P 在模式串 S 中多次作为子串出现。求出模板串 P 在模式串 S 中所有出现的位置的起始下标。

3.Boyer-Moore算法

算法功能:线性复杂度求匹配串在模式串出现的位置

与KMP功能相同但是速度是其3-5倍

4.Z函数(扩展KMP)

算法功能:求对于原串S1的每一个后缀子串与模式串S2的最长公共前缀

例题1:Passwrod

例题2:给定一个长度为n 的字符串s,找到其最短的整周期,即寻找一个最短的字符串t ,使得 可以被若干个t 拼接而成的字符串表示。

5.AC自动机

算法功能:多匹配串在模式串出现的次数

例题1:给定 n 个模式串 s i 和一个文本串 t,求有多少个不同的模式串在文本串里出现过。
两个模式串不同当且仅当他们编号不同。

6.后缀数组(SA)

算法功能:主要有两个数组,通过sa[i]表示将所有后缀排序后第 小的后缀的编号,rank[i]表示后缀 i的排名,也就是通过这两个数组你可以知道排名第几的后缀字符串是谁,并且可以知道一个字符串排名第几。
算法应用:

1.寻找最小的循环移动位置
2.从字符串首尾取字符最小化字典序
3.求LCP(最长公共前缀)

7.后缀自动机(SAM)

算法功能:

1.在另一个字符串中搜索一个字符串的所有出现位置。
2.计算给定的字符串中有多少个不同的子串。
3.字典序第 k 大子串
4.最小循环移位
5.最短的没有出现的字符串
6.两个字符串的最长公共子串
7.所有不同子串的总长度
8.子串出现次数
9.多个字符串间的最长公共子串

例题1:SAM模板

8.后缀平衡树

其中序遍历即为后缀数组。
优点:
1.后缀平衡树的复杂度不依赖于字符集的大小
2.后缀平衡树支持在字符串开头删除一个字符
3.后缀平衡树可持久化
例题1:后缀平衡树模板
例题2:后缀排序

9.广义后缀自动机

后缀自动机 (suffix automaton, SAM) 是用于处理单个字符串的子串问题的强力工具。
而广义后缀自动机 (General Suffix Automaton) 则是将后缀自动机整合到字典树中来解决对于多个字符串的子串问题
例题1:本质不同字串

10.Manacher(马拉车)

算法功能:线性复杂度找到字符串中所有的回文子串

例题1:给定一个长度为 n 的由小写字母构成的字符串,求它的最长回文子串的长度是多少。

11.回文树

算法功能:回文树 (EER Tree,Palindromic Tree,也被称为回文自动机)是一种可以存储一个串中所有回文子串的高效数据结构,使用回文树可以简单高效地解决一系列涉及回文串的问题。

例题1:回文串

12.序列自动机

算法功能:

下面,给两个小写字母串A ,B请你计算:

A 的一个最短的子串,它不是B 的子串
A 的一个最短的子串,它不是 B 的子序列
A的一个最短的子序列,它不是 B的子串
A的一个最短的子序列,它不是 B的子序列
例题1:最短不公共子串

13.最小表示法

字符串 S的最小表示为与 S循环同构的所有字符串中字典序最小的字符串

14.Lyndon 分解

将字符串s唯一分解为若干个简单串
简单串是字典序小于所有后缀串的字符串

15.Main-Lorentz 算法

问题描述:

给定一个长度为n 的字符串 s。

我们将一个字符串连续写两遍所产生的新字符串称为 重串 (tandem repetition)。下文中,为了表述精准,我们将被重复的这个字符串称为原串。换言之,一个重串等价于一对下标 (i,j),其使得s[i…j] 是两个相同字符串拼接而成的。
你的目标是找出给定的字符串 s中所有的重串。

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
算法竞赛入门经典--训练指南,代码仓库,有四个版本的代码仓库。 《算法竞赛入门经典——训练指南》代码仓库 例题代码 限于篇幅,书上并没有给出所有例题的代码,这里给出了所有例题的代码,并且改进了书上的一些代码。 第一章 32题 38份代码 第二章 28题 30份代码 第三章 22题 23份代码 第四章 19题 21份代码 第五章 34题 39份代码 第六章 24题 26份代码 共159题 177份代码 为了最大限度保证代码风格的一致性,所有例题代码均由刘汝佳用C++语言编写。 所有代码均通过了UVa/La的测试,但不能保证程序是正确的(比如数据可能不够强),有疑问请致信[email protected],或在googlecode中提出: http://code.google.com/p/aoapc-book/ [最新更新] 2013-04-23 增加字符串中例题10(UVa11992 Fast Matrix Operations)的另一个版本的程序,执行效率较低,但更具一般性,可读性也更好 2013-04-22 增加字符串部分“简易搜索引擎”代码,可提交到UVa10679 2013-04-13 修正Treap中优先级比较的bug(原来的代码实际上是在比较指针的大小!),加入纯名次树代码 2013-03-31 修正UVa1549标程的bug,即buf数组不够大。 增加线段树部分“动态范围最小值”的完整代码 2013-03-23 修正UVa10054标程的bug,即没有判断是否每个点的度数均为偶数。UVa数据已经更新 LA3401修正了代码和文字不一致的问题 UVa11270增加了答案缓存 2013-03-21 增加线段树部分中两个经典问题的完整代码:快速序列操作I和快速序列操作II 2013-02-28 补全所有159道例题的代码
址开始的连续存储空间,每个转换后的字符占1个字节,不足的用0补足。 好的,我明白了。对于您提出的问题,我可以提供程序代码来解决它。以下是代码: ```assembly assume cs:code, ds:data data segment str1 db 'AB123cdE*87fGabFZ$' ; 输入的字符串 result db 50 dup (0) ; 存储转换后的结果 data ends code segment start: mov ax, data mov ds, ax ; 初始化数据段寄存器 lea si, str1 ; 将si指向输入字符串的起始位置 lea di, result ; 将di指向存储结果的起始位置 cld ; 设置方向标志寄存器,以便向前遍历字符串 mov cl, 50 ; 待遍历字符串长度 xor ax, ax ; 清空ax寄存器 loop1: lodsb ; 从输入字符串中读取1个字节到al cmp al, '$' ; 如果已遍历完整个字符串,则结束 je endloop1 cmp al, 'A' jl lower_case ; 如果al小于'A',则为小写字母 cmp al, 'Z' jle upper_case ; 如果al在'A'~'Z'范围内,则为大写字母 cmp al, 'a' jl other_char ; 如果al小于'a',则为其他字符 cmp al, 'z' jg other_char ; 如果al大于'z',则为其他字符 lower_case: add al, 32 ; al加上32,转换为大写字母 jmp store_char upper_case: sub al, 32 ; al减去32,转换为小写字母 jmp store_char other_char: xor al, al ; 将al清零,表示为0 store_char: mov [di], al ; 将转换后的字符存储到结果中 inc di ; di指向下一个位置,以便存储下一个字符 loop loop1 ; 继续遍历输入字符串 endloop1: mov ah, 4ch ; 退出程序 int 21h code ends end start ``` 希望以上代码可以解决您的问题。如果您有任何其他问题,随时都可以问我。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值