1 / 24

题4 .25

题4 .12. 题4 .13. 题4 .25. 题4 .20. 题4 .28. 题4 .29. 题4 .30. 题 4.12. 利用已知串的 五种基本操作 实现串的置换操作。. pos. pos. i. S 串. sub. T 串. V 串. news 串. sub. V 串. StringType Replace (StringType S, StringType T,

urbana
Download Presentation

题4 .25

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. 题4.12 题4.13 题4.25 题4.20 题4.28 题4.29 题4.30

  2. 题4.12 利用已知串的五种基本操作实现串的置换操作。 pos pos i S 串 sub T 串 V 串 news 串 sub V 串

  3. StringType Replace (StringType S, StringType T, StringType V ) { // T为非空串。若主串S中存在与 T相等的子串,则均以串V替换之。 // 本算法返回被置换后的新串。 n = StrLength(S); m = StrLength(T); i = pos = 1; StrAssign(news, ); while ( i <= n-m+1) { SubString (sub, S, i, m); if (StrCompare(sub,T) != 0) ++i ; else { } } // while S中不再存在与T相等的子串 } // Replace ··· ··· ··· ···

  4. // else news = Concat(news, SubString(S, pos, i-pos)); news = Concat(news, V); i = pos = i + m; // pos指示查询的起始位置; i指示子串的起始位置 // 结尾处理 news = Concat(news, SubString(S, pos, n-pos+1)); return news;

  5. 题4.13 从串S中删除所有和串T相同的子串。 此题的操作等同于“以空串置换串S中所有和串T相同的子串。” 显然,算法的目标是构造如上所画的一个新串。

  6. StringType Delete (StringType S, StringType T) { // T为非空串。若主串S中存在与 T相等的子串,则删除之。 // 本算法返回被删后的 S串。 n = StrLength(S); m = StrLength(T); i = pos = 1; StrAssign(news, ); while ( i <= n-m+1) { SubString (sub, S, i, m); if (StrCompare(sub,T) != 0) ++i ; else { } } // while S中不再存在与T相等的子串 } // Delete ··· ··· ··· ···

  7. // else news = Concat(news, SubString(S, pos, i-pos)); i = pos = i + m; // 结尾处理 news = Concat(news, SubString(S, pos, n-pos+1)); return news;

  8. 题4.20 从串S 中删除所有和串T 相同的子串。 此题的基本思想和题 4.13 相同,所不同的是要求在在串的定长存储表示中实现。 算法的目标是构造如上所画的一个新串。

  9. 删除之前的 S 串 k pos 删除之后的 S 串 算法的基本思想为: S[S[0]+1..S[0]+k-pos] = S[pos.. k-1] 具体写算法时,上述串的赋值是对单个字符进行的,因为在查询过程中,一旦指针 i“回退”,则说明上一次搜索的起始位置的字符肯定不会被删除。详细算法见下页。

  10. void del_sub(SString S, SString T) { k=0; i=1; // k指示新串的当前长度,i指示S串中当前匹配的字符 while (i <= S[0]-T[0]+1) { j=1; while (j<=T[0] && S[i] = T[j] ) { ++i; ++j; } // 继续比较后继字符 if ( !(j > T[0])) //重新开始一轮匹配,并保存“前一字符” { i:=i-j+2; S[++k]:=S[i-1]; } } // while while (i <= S[0] ) { ++k; S[k..k+S[0]-i+1]:=S[i..S[0]]; } // 保存剩余串 S[0] = k+S[0]-i+1; }

  11. 题4.25 解此题的基本思想和题4.12相同,但需要在串的堆存储结构中实现。 由于堆存储结构是按串的实际长度分配空间,则首先需知道置换之后的串的长度。 因此解此题的基本步骤为: 1) 找出所有和 T串相同的子串,并记下它们的起始位置; 2) 计算置换之后的 S 串的长度; 3) 为置换后的串分配空间并逐段复制求得新的 S 串;

  12. void repl(HString &S, HString T, HString V) { 初始化线性表Y为空表; // Y记录和T相同的子串 i=0; while (i <= S.length-T.length) 在S 中查找和 T 相同的子串,共有Y.length个,每一个子串在S 中的初始位置为Y.elem[k]; if (Y.length!=0) { n = S.length; S.length = n + Y.length*(V.length-T.length); ns.ch = new char[S.length]; 逐段复制子串到ns.ch; S.ch = ns.ch; } // if } // repl

  13. void repl(HString &S, HString T, HString V) { Y.length = 0; i = 0; while (i <= S.length - T.length ) { j = 0; while (j<T.length && S.ch[i+j] = T.ch[j]) j++; if ( j < T.length ) i++; // 重新开始新一轮的匹配 else // 找到和T 相同的子串 { Y.elem[Y.length++] = i; i+=T.length; } }//while if ( Y.length != 0 ) { } } ……

  14. n = S.length; S.length += Y.length*(T.length-V.length); ns.ch = new char[S.length+1]; k=1; i=0; spos=0; while(k<Y.length) { tpos=Y.elem[k]-1; len=tpos-spos; ns.ch[i..i+len] = S.ch[spos..tpos]; i+=len+1; ns.ch[i..i+V.length-1] = V.ch[0..V.length-1]; spos = Y.elem[k]+T.length; i+=V.length; k++; } ns.ch[i..S.length-1] = S.ch[spos..n-1]; S.ch = ns.ch;

  15. T V spos tpos spos i+len i i i tpos=Y.elem[k]-1; len=tpos-spos; i+=len+1; spos = Y.elem[k]+T.length; i+=V.length;

  16. void get_next(Lstring T) { p = T.head; q = NULL; p->next = NULL; while (p) { if ( !q || p->ch == q->ch ) { p = p->succ; if (!q) q = T.head; else q = q->succ; if ( p->ch == q->ch ) p->next = q->next; else p->next = q; } else q = q->next; } 题4.28

  17. 题4.29 Link index_L(Lstring S, Lstring T) { p = S.head; q = T.head; while ( p && q ) { if ( p->ch == q->ch ) { p = p->succ; q = q->succ; } else { q = q->next; if (!q) { q = T.head; p = p->succ; } }//while if (q) return NULL; else } …… // 回退找起始位置

  18. p = p->next; q = T.head; while ( q->succ ) { p = p->next; q = q->succ; } return p;

  19. 题4.30 求串S中出现的第一个最长重复子串及其位置。 所谓“重复子串”指的是, SubString(S, i, len) == SubString(S, j, len) 1≤ i<j ≤StrLength(S), 1≤ len ≤StrLength(S)-j+1 例如: S=aaaaaaa的最长重复子串为 T=aaaaaa

  20. 分析: 此题可有多种解法。 一种比较直观的做法是: 在串 S 中取子串 SubString( S, i, len ) 和子串 SubString( S, i+1, StrLength(S)-i ) 相匹配。 假设 S 串的长度为 n, 则 len 的变化范围是从 n-1 到 1 , i 的变化范围是从 1 到 n - len 最坏情况下的时间复杂度为 O(n3)。 另一种作法是,利用 next 函数的特性, 可以使算法的时间复杂度减为 O(n2)。

  21. 因为 next[j]0表明: 在第 j 个字符之前存在一个长度为 next[j]-1 的重复子串。 由此,算法的基本思想为:求各子串 pat[i]=SubString(S,i,StrLength(S)-i+1) 的next 函数值,i=1, 2, …, StrLength(S)- 1并从中求最大值

  22. 例如: S=abaabaaabaaaab Pat[1]= abaabaaabaaaabnext值 0 1 1 22 3 4 52 3 4 5 2 2 Pat[2]= baabaaabaaaabnext值 0 1 1 12 3 4 12 3 4 1 1 Pat[3]= aabaaabaaaabnext值 0 1 2 12 3 3 45 6 7 3 Pat[4]= abaaabaaaabnext值 0 1 1 22 2 3 4 56 2

  23. i=1; maxl=0; n=S[0]; while(n-i+1>maxl) { maxk=Max{Next(SubString(S, i ,n-i+1))}; if (maxk!=next[n] || S[n]!=S[i+maxk-1]) maxk--; if (maxk>maxl) { maxl=maxk; spos=i; } i++; }

  24. 算法的基本思想为: 求 pat[i] = SubString( S, i, n-i+1 ) i=1,2,…,n-1 的 next 函数值中的最大值。 i = 1; maxl = 0; spos = 0; n = S[0]; while ( n-i+1 > maxl ) { 求 pat[i] = SubString( S, i, n-i+1 ) 的 next[j]中 的最大值 len[i] = next[j]; if ( len[i] > maxl ) { maxl = len[i]; 记下子串pat[i] 的起始位置; } i++; }

More Related