1 / 86

本节内容有难度,考试不做要求。但是某些学校的考研课要考。主要强调思想,程序不多说。

本节内容有难度,考试不做要求。但是某些学校的考研课要考。主要强调思想,程序不多说。. 4.2.2 堆分配存储表示 这种存储方式和前面的顺序表相仿,采用动态数组来存储串,数组的大小会随着串的变化而进行调整。 下面实现堆表示的串及其基本操作:. #include <iostream> using namespace std; struct SString// 串 { char *s;// 存储串中字符 int str_len; };. int strlen(SString s)// 求串的长度 { return s.str_len; } ///

lara-love
Download Presentation

本节内容有难度,考试不做要求。但是某些学校的考研课要考。主要强调思想,程序不多说。

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 本节内容有难度,考试不做要求。但是某些学校的考研课要考。主要强调思想,程序不多说。本节内容有难度,考试不做要求。但是某些学校的考研课要考。主要强调思想,程序不多说。

  2. 4.2.2堆分配存储表示 这种存储方式和前面的顺序表相仿,采用动态数组来存储串,数组的大小会随着串的变化而进行调整。 下面实现堆表示的串及其基本操作:

  3. #include <iostream> using namespace std; struct SString//串 { char *s;//存储串中字符 int str_len; };

  4. int strlen(SString s)//求串的长度 { return s.str_len; } /// int str_assign(SString &s1,char *s2) { int len=strlen(s2);//假定s2的长度不会超过MAXSTRLEN s1.str_len=len; s1.s=new char[len+1];//第0个单元不用 for(int i=1;i<=len;i++) s1.s[i]=s2[i-1]; return 1; }

  5. int str_insert(SString &s,int i,char a)//在串中插入一个字符 { int len=strlen(s); if(i<1 || i>len+1) return 0;//越界 char *temp=new char[len+1+1];//0单元不用,又增加一个 for(int j=1;j<=i-1;j++) temp[j]=s.s[j]; temp[i]=a; for(j=i+1;i<=len;j++,i++) temp[j]=s.s[i]; s.str_len++; delete []s.s; s.s=temp; return 1; }

  6. int str_copy(SString &s1,SString &s2) {//将s2中字符串拷贝到s1中 char *temp=new char[s2.str_len]; //delete []s1.s; //s1.s=temp; for(int i=1;i<=strlen(s2);i++) temp[i]=s2.s[i]; s1.str_len=s2.str_len ; delete []s1.s; s1.s=temp; return 1; }

  7. void str_cat(SString &s0,SString s1,SString s2) {//将s2连接到s1的后面,结果存放在s0中,若空间不够则截断 s0.s=new char[s1.str_len+s2.str_len+1]; //0单元不用 s0.str_len=s1.str_len+s2.str_len; for(int i=1;i<=s1.str_len;i++) s0.s[i]=s1.s[i]; for(int j=1;j<=s2.str_len;j++,i++) s0.s[i]=s2.s[j]; }

  8. int str_index(SString s,SString t,int pos) {//从第pos个位置开始查找t在s中出现的第一个位置 if(pos<1) return 0; int start=pos,end=s.str_len-t.str_len+1; for(int i=start;i<=end;i++) { for(int j=1,k=i;j<=t.str_len;j++,k++) { if(s.s[k]!=t.s[j]) break; } if(j>t.str_len)return i; } return 0; }

  9. void print(SString &s) { for(int i=1;i<=strlen(s);i++) cout<<s.s[i]; cout<<endl; } //////////

  10. int main(int argc, char* argv[]) { SString a,b; str_assign(a,"abc"); str_assign(b,"def"); print(a); print(b); ::str_insert(a,2,'m'); print(a); ::str_copy(a,b); print(a); str_assign(a,"aaa"); str_assign(b,"bbb"); print(a);print(b); SString c; str_cat(c,a,b); print(c); str_assign(a,"abcdefghijklmn"); str_assign(b,"defg"); print(a); print(b); cout<<str_index(a,b,1)<<endl; return 0; }

  11. 4.3 串的模式匹配算法 4.3.1 传统的模式匹配算法(前面已经介绍) 4.3.2 KMP算法 先看KMP算法的执行过程,然后来解释其思想

  12. KMP算法

  13. 在主串s=“acabaabaabcacaabc”中 查找模式串t=“abaabcac”

  14. j a a c a b a a b a b c a c c a a b i 2 4 a 0 a 1 2 b 1 1 3 a c 6 3 a 7 1 5 2 b 8 c 2 模式串 Next[j]

  15. i j a a c a b a a b a b c a c c a a b i 2 4 a 0 a 1 2 b 1 3 1 a 3 6 c a 1 7 5 2 b 8 2 c 模式串 Next[j] 不等,根据Next[j],让模式串回溯到1,即j=1

  16. j a a c a b a a b a b c a c c a a b i 2 4 a 0 a 1 2 b 1 3 1 a 3 6 c a 1 7 5 2 b 8 2 c 模式串 Next[j] 不等,根据Next[j],此时next[j]=0,令j=1,i后移

  17. j a a c a b a a b a b c a c c a a b i 2 4 a 0 a 1 2 b 1 1 3 a c 6 3 a 7 1 5 2 b 8 c 2 模式串 Next[j]

  18. j a a c a b a a b a b c a c c a a b i 2 4 a 0 a 1 2 b 1 1 3 a c 6 3 a 7 1 5 2 b 8 c 2 模式串 Next[j]

  19. j a a c a b a a b a b c a c c a a b i 2 4 a 0 a 1 2 b 1 1 3 a c 6 3 a 7 1 5 2 b 8 c 2 模式串 Next[j]

  20. j a a c a b a a b a b c a c c a a b i 2 4 a 0 a 1 2 b 1 1 3 a c 6 3 a 7 1 5 2 b 8 c 2 模式串 Next[j]

  21. j a a c a b a a b a b c a c c a a b i 2 4 a 0 a 1 2 b 1 1 3 a c 6 3 a 7 1 5 2 b 8 c 2 模式串 Next[j]

  22. j a a c a b a a b a b c a c c a a b i 2 4 a 0 a 1 2 b 1 3 1 a 3 6 c a 1 7 5 2 b 8 2 c 模式串 Next[j] 不等,根据Next[j],让模式串回溯到3,即j=3

  23. j a a c a b a a b a b c a c c a a b i 2 4 a 0 a 1 2 b 1 1 3 a c 6 3 a 7 1 5 2 b 8 c 2 模式串 Next[j]

  24. j a a c a b a a b a b c a c c a a b i 2 4 a 0 a 1 2 b 1 1 3 a c 6 3 a 7 1 5 2 b 8 c 2 模式串 Next[j]

  25. j a a c a b a a b a b c a c c a a b i 2 4 a 0 a 1 2 b 1 1 3 a c 6 3 a 7 1 5 2 b 8 c 2 模式串 Next[j]

  26. j a a c a b a a b a b c a c c a a b i 2 4 a 0 a 1 2 b 1 1 3 a c 6 3 a 7 1 5 2 b 8 c 2 模式串 Next[j]

  27. j a a c a b a a b a b c a c c a a b i 2 4 a 0 a 1 2 b 1 1 3 a c 6 3 a 7 1 5 2 b 8 c 2 模式串 Next[j]

  28. j a a c a b a a b a b c a c c a a b i 2 4 a 0 a 1 2 b 1 3 1 a 3 6 c a 1 7 5 2 b 8 2 c 模式串 Next[j] 成功

  29. 可以看出KMP算法比传统的算法要快得多。其中的关键是模式串的Next函数怎样求。可以看出KMP算法比传统的算法要快得多。其中的关键是模式串的Next函数怎样求。 下面看一下推导过程。 假设主串为:“s1s2….sn”,模式串为:“p1p2…..pm” 假定在某个时刻,si和pj不相等,那么此时p(j-1)到p1跟s中相应位置字符相同,所以有下面的等式: p1p2…p(j-1)=s(i-j+1)….s(i-1) 此时假定模式串回溯到第k个位置就能够继续向下进行比较,那么也有等式: p1p2….pk=s(i-k+1)….s(i) -------〉 p1p2….p(k-1)=s(i-k+1)….s(i-1) 此时k<j

  30. 即有下面关系: 所以有 p(j-k+1)….p(j-1)=p1….p(k-1)

  31. 因为k<j;从上面式子观察可得,k>=2,则j>=3。 令j=1时,k=0;可以理解为:当第一个字符不相等时,主串的指针后移一个位置,模式串从第一个字符开始。那么也可以理解为模式串回溯到第0个字符和主串进行比较,因为不存在第0个字符,所以跟上面的意思一样。 令j=2时,k=1。即当第二个字符不等时,模式串回溯到第1个字符进行比较。 其他情况下,next[j]=k=Max{k| p(j-k+1)….p(j-1)=p1….p(k-1)},比字符串长度多1。

  32. Next[j]的手工求法

  33. 根据定义next[1]=0

  34. 根据定义next[2]=1

  35. 没有相等的串,故j=3时,回溯到0+1=1

  36. 没有相等的串,故j=3时,回溯到0+1=1

  37. 不等,看更短的串是否相等

  38. 相等,没有更短的串

  39. 所以j=4时,应该回溯到1+1=2

  40. 所以j=4时,应该回溯到1+1=2

  41. 不等,看更短的串是否相等

  42. 不等,看更短的串是否相等

  43. 所以j=5时,应该回溯到1+1=2

  44. 不等,看更短的串是否相等

  45. 不等,看更短的串是否相等

More Related