第四章学习小结
Posted guanzetao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第四章学习小结相关的知识,希望对你有一定的参考价值。
这两周上课学的较多且比较有印象的是串的模式匹配算法那道题
同时可以用BF或者KMP算法进行解决。
一开始学BF算法时就在想如何改进可以使匹配更加简便
后来KMP的学习让我对串的学习有了更深入的了解
同时BF和KMP算法之间的联系也是一个算法改进的很好学习范例
7-1 串的模式匹配
给定一个主串S(长度<=10^6)和一个模式T(长度<=10^5),要求在主串S中找出与模式T相匹配的子串,返回相匹配的子串中的第一个字符在主串S中出现的位置。
输入格式:
输入有两行: 第一行是主串S; 第二行是模式T.
输出格式:
输出相匹配的子串中的第一个字符在主串S中出现的位置。若匹配失败,输出0.
输入样例:
在这里给出一组输入。例如:
aaaaaba
ba
输出样例:
在这里给出相应的输出。例如:
6
在这道题中原本使用BF或者KMP算法都可以解决,但是老师修改了主串和模式串的长度后,使用BF算法在长度的测试点中会因为超时而无法通过,因而要通过所有测试点,只能使用KMP算法。
1 #include<iostream>
2 #include<string.h>
3 using namespace std;
4 char* a(string str){
5 int size = str.length();
6 char *s;
7 s= new char[size];
8 strcpy(s, str.c_str());
9 return s;
10 }
11 void b_next(string Pstring, int *next){
12 next[0] = -1;
13 int j = 0, k = -1;
14 int p_len = Pstring.length();
15 char *p = a(Pstring);
16 while(j<p_len){
17 if(k == -1 || p[j] == p[k]) {
18 k++;
19 j++;//k:开始前缀下标,j:后缀下标
20 next[j] = k;
21 }else{
22 k = next[k]; //k回溯
23 }
24 }
25 }
26 int kmp(string Sstring, string Pstring){
27 int *next = new int[Pstring.length()];
28 b_next(Pstring, next);//获取next[]数组
29 char *s = a(Sstring);
30 char *p = a(Pstring); //转换为字符数组
31 int i=0, j=0;
32 int pos = 0;
33 while( i<=Sstring.length() || j<=Pstring.length()){
34 if( j == -1 || s[i] == p[j]){
35 i++;
36 j++;
37 }else{
38 j = next[j];
39 }
40 if(j == Pstring.length()){
41 pos = i-j+1;
42 break;
43 }//成功匹配
44 }
45 return pos;
46 }
47 int main()
48 {
49 string Sstring, Pstring;//定义字符串
50 getline(cin, Sstring);
51 getline(cin, Pstring);//输入字符串
52 cout<<kmp(Sstring, Pstring);
53 return 0;
54 }
个人理解KMP相较于BF算法,比较特别的是next数组的获取。
next数组中,与其对应的每个字符的值为其前面字符的前后缀(最长),令next[0]=-1(下标比较)。给出任意一个模式串,即可确定它的next数组值。
e.g.
a b c d a b d, next[j]={-1,0,0,0,0,1,2}。
用next指针接受指针函数传来的数组地址
如果s【j】 == p【j】当前字成功匹配
next【j】便是j对应的next值接着返回第一次匹配位置
主串S的指针i不必回溯便可使原本BF算法的O(m*n)变为O(m+n)
学习内容中pk,pj的计算,如“设next【j】=k,则next【j+1】=?”之类的问题,在课后也是看PPT看了很久才明白
感觉这几节课学得比起往前更为充实,这两周敲代码的时间也比之前多了许多。
上课效率感觉高了很多,但是还是有待改进,比如上机老师讲题目那节课效率很差导致后面做那道题花了比别人更多的功夫。
接下来保持前几节课的效率,同时多做些编程练习,感觉自己的编写代码能力与其他优秀的同学比还有很大差距,要慢慢跟上大部队。
以上是关于第四章学习小结的主要内容,如果未能解决你的问题,请参考以下文章