第四章学习小结

第四章,学习了串,数组和广义表。

数组的,其实不难理解,找找规律就ok了。

在学习串的模式匹配算法的时候,BF算法,很快就看懂了,但是KMP算法有点抽象,折腾了很久。后来整理了一下,大致弄清楚了这个算法的思路,但是对于next函数的实现还是有点问题,后续会继续跟进一下。在做第四章作业的编程题里,开始我用的就是BF算法,很快就写出来了,不过通过不了最后一个测试点,时间复杂度太大了,然后对着课本,改成了KMP算法之后,才通过最后一个测试点。

具体代码实现如下,注释起来的是使用BF算法的。

 1 #include <iostream>
 2 #include <string.h>
 3 #include <string>
 4 using namespace std;
 5 
 6 /*
  BF
  int match(string s, string t) 7 { 8 int i=0, j=0; 9 int x=0;//表示第几趟 10 while(s[i]!='\0'&&t[j]!='\0') 11 { 12 if(s[i]==t[j])//字符比较相等 13 { 14 i++; j++; 15 } 16 else 17 { 18 x++; 19 j=0; 20 i=x; 21 } 22 } 23 if(s[i]=='\0'&&t[j]!='\0') return 0; 24 else return (i-j+1); 25 }*/ 26 27 void kmp_next(string t, int next[]) 28 { 29 next[0]=-1;//-1表示模式串开头 30 int j=0, k=-1; 31 32 while(j<t.length())//当j尚未指向模式串尾端时 33 { 34 if(k==-1||t[j]==t[k]) 35 { 36 k++;//k指前缀开始下标 37 j++;//j指后缀开始下标 38 if(t[j]==t[k]) 39 { 40 41 next[j]=next[k];//next[]存放已匹配子串中最长前后缀长度 42 //其中,next[j]表示t[0]-t[j-1]子串中最长前后缀长度 43 } 44 else next[j]=k;//next[]存放已匹配子串中最长前后缀长度 45 } 46 47 else k=next[k];//k回溯到模式串开 48 } 49 } 50 51 int KMP(string s, string t) 52 { 53 int i=0, j=0, pos=0; 54 int next[t.length()]; 55 kmp_next(t, next); 56 while(i<=s.length()||j<=t.length()) 57 { 58 /*有最长前后缀,主串和模式串在t[j]位置不匹配,即 59 模式串最长后缀后一位不匹配,s[i]和最长前缀后一位比较, 60 无最长前后缀,j=next[0]=-1,将整个模式串后移一位*/ 61 if(j==-1||s[i]==t[j]) 62 { 63 i++; j++; 64 } 65 else j=next[j]; 66 67 if(j==t.length())//匹配成功 68 { 69 pos=i-j+1; 70 break; 71 } 72 } 73 return pos; 74 } 75 76 int main() 77 { 78 string S, T;//S是主串,T是模式串 79 getline(cin, S); 80 getline(cin, T); 81 int tag; 82 tag=KMP(S, T); 83 cout << tag; 84 return 0; 85 }

对于实践题的代码,也是遇到时间复杂度的问题,我是使用数组,尝试过先将a,b数组按非降序排列再求交集,和求交集写入c数组再将c数组非降序排列,在排列的时候使用过选择排序,插入排序(其实还查到别的排序方法,不过没有用,有一些还不是很理解),都没有解决到最后一个测试点的问题,最后在网上查到一个sort函数,sort(a, a+n),将a[0]到a[n]进行非降序排序,使用过这个函数之后解决了最后一个测试点的问题。不知会不会还有不使用sort也能通过的方法,之后再学习一下,下面是使用sort的代码

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 int main()
 5 {  int n,m;
 6    int a[100000],b[100000],c[200000];//定义数组 
 7    cin>>n>>m;//
 8 
 9    for (int i=0; i < n; i++)
10          cin>>a[i];
11 
12    for (int i=0; i < m; i++)
13          cin>>b[i];//输入指定的数组数据 
14 
15    sort(a,a+n);
16 
17    sort(b,b+n);//对数组数据进行排序 
18 
19    int i=0,j=0,k=0;
20 
21    while (i<n && j<m) //判断两个数组的数据大小,用数组c记录下相同的数据,并记录好相等的次数(有多少个交集)
22 {
23        if (a[i]==b[j]) 
24             c[k++]=a[i],i++,j++;
25       else
26       if (a[i]<b[j])
27             i++;
28       else 
29             j++;
30 }
31    cout<<k<<endl;
32    for (int i=0; i < k; i++) 
33 {
34          cout<<c[i];//输出数组,按照要求取好空格与最后没有空格 
35    if(i!=k-1)
36        {    cout<<" ";}
37 }
38 return 0;
39 }

第四章学习,出来KMP算法还有某个点不是很理解之外,其他都还ok,在下一阶段会继续努力,把各个知识点都弄透。

 

posted @ 2020-05-03 11:44  Jadfhjva  阅读(202)  评论(0编辑  收藏  举报