1
0
mirror of https://github.com/Didnelpsun/CS408.git synced 2026-06-16 15:07:38 +08:00

串更新

This commit is contained in:
Didnelpsun
2021-04-24 23:45:35 +08:00
parent ae6008c306
commit 5dc818f9af
3 changed files with 61 additions and 2 deletions

View File

@@ -17,6 +17,7 @@
+ 使用单独的变量length保存串长。
+ 使用data[0]记录串长使得字符位序与数组下标一致但是由于char类型一个为一字节大小所以能表示的数字是0到255太大的串无法表示。
+ 没有表示串长的变量,使用\0表示串结尾对应ASCII码的0号字符。
+ data[0]空余使用单独的变量length保存串长这个比较常用。
## 链串
@@ -32,7 +33,7 @@
### 朴素模式匹配算法
从主串、模式串子串的第一个位置开始比较i=0,j=0若相等则 ij 各自+1然后比较下一个字符。若不等主串指针回溯到上一轮比较位置的下一个位置子串回溯到0再进行下一次比较。令子串长度为m主串长度为n
从主串T、模式串P子串的第一个位置开始比较i=0,j=0若相等则 ij各自+1然后比较下一个字符。若不等主串指针回溯到上一轮比较位置的下一个位置子串回溯到0再进行下一次比较。令子串长度为m主串长度为n
+ 匹配成功的最好时间复杂度:$O(m)$:刚好第一个就匹配上了,总对比次数为子串长度。
+ 匹配失败的最好时间复杂度:$O(n-m+1)=O(n-m)=O(n)$:匹配成功之前,每一个与第一个字符都匹配失败。
@@ -42,5 +43,20 @@
KMP算法是对朴素模式匹配算法的优化。
主要思想是失配时,只有模式串指针回溯,主串指针不变
朴素模式匹配算法的缺点就是当某些子串与模式串能部分匹配时主串的扫描指针i经常回溯从而导致时间开销
主要思想是失配时,只有模式串指针回溯,主串指针不变,找到失配前模式串的最长公共前后缀并跳转到最大公共后缀开始匹配,且最大公共前后缀要小于左端子串长度。
+ 前缀对于字符串ABA=B+S且S非空则B是A的前缀。
+ 后缀对于字符串ABA=S+B且S非空则B是A的后缀。
+ PMT值前缀集合和后缀集合的交集中最长元素的长度。
+ 部分匹配表PMT值集合字符串所有前后缀的PMT值。
当一个位置失配时那么子串前面的所有字符串都是配对的所以对于子串前面的部分都是已知的了需要从模式串的最开始开始对比而一般的模式匹配要从主串的下一个重新开始匹配但是如果我们找到了主串当前失配位置的前缀和后缀最大重合的地方即公共前后缀PMT值就代表从这里开始就可以匹配了前面的地方没必要匹配可以直接多跳几步移动到公共后缀去开始重新匹配。
当第j个字符匹配失败由P前1到j-1个字符组成的串记为S则next[j]=S的最长相等前后缀长度+1即最大PMT值+1。特别的next[1]=0且next[2]肯定为1。
使用KMP算法时需要先计算不同模式串P的next数组时间复杂度为$O(m)$然后使用KMP算法计算时间复杂度为$O(n)$,从而平均时间复杂度为$O(m+n)$。
KMP算法对于重复部分比较多的模式串匹配效果更好。