KMP算法的正确性证明及一个小优化

本文详细介绍了KMP算法的正确性,包括匹配过程和前缀函数计算的正确性,并提供了时间复杂度分析。此外,文章还提出了一种优化方法,通过改进前缀函数构造,降低失配概率,尤其适用于包含重复子串的模式串。
直接把作业帖上来是不是有点不太公道呀。。。
  
  无所谓啦反正各位看着开心就行KMP算法对于模式串PP,建立其前缀函数NN ,其中N[q]N[q] 表示在PP中,以qq位置为结束的可以匹配到前缀的最长后缀的长度(也可以理解为那个前缀的结束位置),在匹配中,若P[i]P[i]与S[j]S[j]失配,则令i=N[i?1]+1i=N[i?1]+1 ,否则现考虑如何构造NN ,设当前以计算出N[1..i?1]N[1..i?1] ,则令k=N[i?1]k=N[i?1] ,若 P[k+1]=P[i]P[k+1]=P[i],则令N[i]=k+1N[i]=k+1 ,否则令k=N[k]k=N[k] 。重复上述过程,直至找到可证该算法能在Θ(|P|)Θ(|P|) 的时间内构造出前缀函数NN ,在Θ(|S|)Θ(|S|) 的时间内完成匹配,总的时间复杂度为KMP算法的正确性证明先证明匹配过程的正确性:在过程中,若P[1..q]P[1..q] 与S[s+1...s+q]S[s+1...s+q] 匹配,而P[q+1]P[q+1]与S[s+q+1]S[s+q+1] 失配,那么由NN的定义可立即得出P[1..N[q]]P[1..N[q]] 与 S[s+q?N[q]+1...s+q]S[s+q?N[q]+1...s+q] 匹配,而S[1...t]S[1...t]与S[s+q?t+1...s+q]S[s+q?t+1...s+q] 失配(N[q]<t<q)(N[q]<t<q) ,即只需检验P[N[q]+1]P[N[q]+1] 与S[s+q+1]S[s+q+1] 的匹配情况即可,匹配过程的正确性即可得证。
  
  接下来证明前缀函数NN计算的正确性:令N?[q]={N[q],N(2)[q],…,N(t)[q]}N?[q]={N[q],N(2)[q],…,N(t)[q]} 其中N(t)[q]=N(t?1)[q],N(0)[q]=N[q]N(t)[q]=N(t?1)[q],N(0)[q]=N[q] ,那么N?[q]N?[q] 为以q位置为结束的可以匹配到前缀的后缀的所有长度(即匹配到所有前缀的位置),同时有N[q]?1∈N?[q?1]N[q]?1∈N?[q?1] ,因此只需从大到小枚举N?[q?1]N?[q?1] 中的元素并通过判
### 如何使用 PlantUML 绘制PlantUML 是一种基于纯文本的语言,能够轻松创建各种 UML 表。以下是关于如何使用 PlantUML 进行绘的核心知识点。 #### 1. 基本语法结构 PlantUML 文件通常以 `@startuml` 开头,并以 `@enduml` 结束。所有的表定义都位于这两个标记之间[^1]。 ```plaintext @startuml ... 表定义 ... @enduml ``` #### 2. 创建简单的类 以下是一个基本的类示例: ```plaintext @startuml class ClassA { - int id - String name } class ClassB { - float value } ClassA --> ClassB : has a relationship @enduml ``` 上述代码展示了两个类之间的关系,其中 `ClassA` 和 `ClassB` 存在一个关联关系。 #### 3. 活动中的标和像 为了增强活动的表现力,可以通过引入标或片来装饰节点。例如,在描述智能驾驶系统时,可以加入交通信号灯或其他相关形。 ```plaintext @startuml (*) --> "Start Driving" :<<icon-car>> Drive to destination; if (Traffic Light?) then (Red) :Stop!; else :Continue driving; endif --> (*) @enduml ``` 这里通过 `<<icon-car>>` 添加了一个汽车标,使得流程更形象化。 #### 4. C4-PlantUML 扩展功能 如果希望构建软件架构,则可考虑采用 C4-PlantUML 工具集。它允许开发者按照 Context、Container、Component 及 Code 层次描绘应用体系结构[^2]。 ```plaintext @startuml !include https://raw.githubusercontent.com/RicardoNiepel/C4-PlantUML/master/src/c4.puml Person(user, "User", "Interacts with the system") System_Boundary(cio, "CI/CD") { System(devops_tooling, "DevOps Tooling", "Supports development processes") } Rel(user, devops_tooling, "uses") @enduml ``` 此脚本利用了外部库文件实现标准样式布局。 #### 5. 配合 Node.js 自动化生成 对于需要批量处理或者集成到 CI/CD 流程的情况,node-plantuml 提供了一种便捷方式调用命令行接口完成转换操作[^3]。 安装模块: ```bash npm install --save-dev node-plantuml ``` 运行样例 JavaScript 脚本: ```javascript const plantuml = require('node-plantuml'); let gen = plantuml(); gen.render('@startuml\nAlice -> Bob: Hello!\n@enduml', function(err, result){ console.log(result); }); ``` 以上程序片段演示了怎样借助编程手段动态生成并查看 uml 输出结果。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值