更新数据结构第四章

This commit is contained in:
Alice-and-Bob
2020-07-10 21:24:26 +08:00
parent b17f4cfab0
commit b7ed39eefb
5 changed files with 136 additions and 12 deletions

View File

@@ -24,19 +24,20 @@
+ [x] [第六章 应用层](https://github.com/Alice-and-Bob/CS408/blob/master/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E7%AC%AC%E5%85%AD%E7%AB%A0%20%E5%BA%94%E7%94%A8%E5%B1%82/%E7%AC%AC%E5%85%AD%E7%AB%A0%20%E5%BA%94%E7%94%A8%E5%B1%82.xmind)
## 数据结构
+ [x] [第一章 绪论](https://github.com/Alice-and-Bob/CS408/blob/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E7%AC%AC%E4%B8%80%E7%AB%A0%20%E7%BB%AA%E8%AE%BA/%E7%AC%AC%E4%B8%80%E7%AB%A0%20%E7%BB%AA%E8%AE%BA.xmind)
+ [x] 第二章 线性表
+ [ ] 第三章 栈和队列
+ [ ] 第四章 树与二叉树
+ [ ] 第五章
+ [ ] 第六章 查找
+ [ ] 第七章 排序
## 网络安全基础与应用
+ [x] 第一章 概论
+ [x] 第二章 密码学
+ [ ] 第三章 应用安全
+ [ ] 第四章 系统安全
+ [x] [第二章 线性表](https://github.com/Alice-and-Bob/CS408/blob/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E7%AC%AC%E4%BA%8C%E7%AB%A0%20%E7%BA%BF%E6%80%A7%E8%A1%A8/%E7%AC%AC%E4%BA%8C%E7%AB%A0%20%E7%BA%BF%E6%80%A7%E8%A1%A8.xmind)
+ [x] [第三章 栈和队列](https://github.com/Alice-and-Bob/CS408/blob/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E7%AC%AC%E4%B8%89%E7%AB%A0%20%E6%A0%88%E5%92%8C%E9%98%9F%E5%88%97/%E7%AC%AC%E4%B8%89%E7%AB%A0%20%E6%A0%88%E4%B8%8E%E9%98%9F%E5%88%97.xmind)
+ [x] 第四章
+ [ ] 第五章 树与二叉树
+ [ ] 第六章
+ [ ] 第七章 查找
+ [ ] 第八章 排序
## 操作系统
## 计算机组成原理
## 网络安全基础与应用
+ [x] 第一章 概论
+ [x] 第二章 密码学
+ [x] 第三章 应用安全
+ [ ] 第四章 系统安全

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@@ -0,0 +1,123 @@
# 简单的模式匹配算法
> 思路暴力匹配用子串T的第一位去跟主串S的每一位进行比对如果相等则比对下一位如果不等则子串T复位到第一位主串S复位到第一次匹配成功位置的下一个字符再进行比对。
> 最坏时间复杂度:**O(mn)**mn分别为主串子串长度
```cpp
int Index(SString S, SString T){
int i=1, j=1;
while(i<=S.length() && j<=T.length()){
if(S.ch[i] == T.ch[j]){ //如果匹配就继续匹配后续字符
++i;
++j;
}
else{
i = i-j+2; //指针后退重新开始分配
j=1;
}
}
if(j>T.length()) return i-T.length();
else return 0;
}
```
> :
$[](%202020-07-10%20160539.png)
# KMP算法
## 普通算法的缺点和对此的改进
S和子串T部分匹配使S和子串TS的i处T的j处失配i处向前看T开头看S来说T使
![](v2-67dd66b86323d3d08f976589cf712a1a_1440w.png)
## 引入部分匹配值、PM表、next数组
> `'ababa'`
> | | | | | |
> | :---: | :-----: | :-----: | :-: |:---: |
> |`'a'` | | | | 0 |
> |`'ab'` | {a} | {b} | | 0 |
> |`'aba'` | {a, ab} | {a, ba} | {a} | 1 |
> |`'abab'` | {a, ab, aba} | {b, ab, bab} | {ab} | 2 |
> |`'ababa'` | {a, ab, aba, abab} | {a, ba, aba, baba} | {aba} | 3 |
PM表
> | | S | PM |
> | :-: | :-: | :-: |
> | 1 | a | 0|
> | 2 | ab | 0|
> | 3 | aba | 1|
> | 4 | abab | 2|
> | 5 | ababa | 3|
` = - `
PM表在使用过程中有较多不便i处失配时i-1PM值PM表整体右移一位-1next数组
T的指针指向哪里开始重新匹配`T[next[j]+1]`
## 机器求解next数组与KMP算法代码
```cpp
void get_next(String T, int next[]){
int i=1, j=0;
next[1]=0;
while(i<T.length()){
if(j == 0||T.ch[i] == T.ch[j]){
++i;
++j;
next[i]=j;
}
else{
j = next[j]+1;
}
}
}
```
next数组的过程完全可以看成字符串匹配的过程next值就是匹配成功的字符串的长度
```cpp
int KMP(char * t, char * p)
{
int i = 0;
int j = 0;
while (i < strlen(t) && j < strlen(p))
{
if (j == -1 || t[i] == p[j])
{
i++;
j++;
}
else
j = next[j];
}
if (j == strlen(p))
return i - j;
else
return -1;
}
```
**KMP算法的时间复杂度为O(m+n)**
# 修正的KMP算法
> next数组在某些情况下会产生错误
>
> `T_j=T_next(j)``next[j]``next[next[j]]`nextval
```cpp
void get_nextval(String T, int nextval[]){
int i=1, j=0;
nextval[1]=0;
while(i<.T.length()){
if(j==0||T.ch[i]==T.ch[j]){
++j;
++i;
if(T.ch[i]!=T.ch[j])
nextval[i]=j;
else
nextval[i]=nextval[j]
}
else{
j=nextval[j];
}
}
}
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.