广东省汕头市金山中学高中信息技术竞赛班数据结构专项培训教程04串教案
广东省汕头市金山中学高中信息技术奥林匹克信息学竞赛

集合与记录类型§6.1 集合类型§6.1.1 集合类型的定义集合是同类型对象的一个汇集,它是指同类型对象汇集在一起构成的数据结构。
集合的每一个对象称为集合的元素。
集合元素必须是有序简单数据类型,集合元素的类型称为集合的基类型。
集合的一般形式为:TYPE <类型标识符> = set of <基类型>;基类型可以是整型、字符型、布尔型、枚举型、子界型等,但不能是实型或结构类型。
例如:TYPE letter = set of ‘A’.. ‘Z’;var ch1, ch2 : letter;也可以直接写成:var ch1, ch2 : set of ‘A’.. ‘Z’;在Pascal中集合是用一组括在方括号中的元素来表示,元素之间用逗号分隔。
如:[A, B , C , D] 是四个枚举量的集合[ 1 .. 20 ] 表示1到20的所有整数的集合[ ‘0’ ] 是单元素集[ ] 表示空集一个集合类型变量的取值,可以是基类型中所有元素按不同的组合而构成的子集。
例如,上面说明变量ch1的类型是letter,它可以是下列的组合:[‘A’ .. ‘Z’] 全集[‘A’, ‘B’, ‘Q’] 任一子集[‘A’ .. ‘C’ , ‘X’ ..‘Z’ ][‘A’ ] 单元素集[ ] 空集空集与所有的集合类型都兼容。
§6.1.2 集合类型的运算ch1:=[ [‘A’ .. ‘C’]];是合法的集合赋值。
对集合除可以进行赋值运算外,还可以进行以下运算:·交(*)运算:两集合之交 S1*S2 为一集合,所得元素由S1、S2中相同的元素组成。
如: [ 0..7 ] * [ 0..4 ] = [ 0..4 ]·并(+)运算:两集合之并 S1+S2 为一集合,所得元素由S1、S2中所有相同的元素组成。
如: [ 0..7 ] + [ 0..4 ] = [ 0..7 ][ 0 , 1 ] + [ 1 , 4 , 6 ] = [ 0 , 1 , 4 , 6 ]·差(-)运算:两集合之差 S1-S2 为一集合,所得元素由只存在于S1而不在S2的那些元素组成。
广东省汕头市金山中学高中信息技术竞赛班第二阶段培训第六课集合与记录类型的综合应用教案

- 各组代表依次上台展示讨论成果,包括主题的现状、挑战及解决方案。
- 其他学生和教师对展示内容进行提问和点评,促进互动交流。
- 教师总结各组的亮点和不足,并提出进一步的建议和改进方向。
6. 课堂小结(5分钟)
目标:回顾本节课的主要内容,强调集合与记录类型综合应用的重要性和意义。
过程:
- 简要回顾本节课的学习内容,包括集合与记录类型的基本概念、组成部分、案例分析等。
4. 学生小组讨论(10分钟)
目标:培养学生的合作能力和解决问题的能力。
过程:
- 将学生分成若干- 小组内讨论该主题的现状、挑战以及可能的解决方案。
- 每组选出一名代表,准备向全班展示讨论成果。
5. 课堂展示与点评(15分钟)
目标:锻炼学生的表达能力,同时加深全班对集合与记录类型的认识和理解。
四、教学资源
1. 软硬件资源:计算机教室、投影仪、电子白板、网络连接。
2. 课程平台:学校内部的教学管理系统、在线学习平台。
3. 信息化资源:《高中信息技术竞赛教程》第二阶段培训用书、教学PPT、案例分析文档、在线练习题库。
4. 教学手段:讲授法、案例分析法、小组讨论法、实践操作法、互动提问法。
五、教学过程设计
3. 学生可能遇到的困难和挑战:在学习集合和记录类型的综合应用时,学生可能会遇到以下困难和挑战:首先,对于集合和记录类型的概念和操作理解不够深入,难以将其应用于实际问题中。其次,对于集合和记录类型的综合应用场景和解决方法不够清晰,难以灵活运用所学知识解决实际问题。此外,学生在实际操作过程中可能会遇到一些具体的技术难题,如集合的交集、并集和差集运算等,需要通过实践和指导来克服。
2. 集合与记录类型基础知识讲解(10分钟)
广东省汕头市金山中学高中信息技术竞赛班数据结构专项培训教程06广义表教案

§6 广义表§6.1 广义表的定义广义表(Lists)又称列表,是线性表的推广,广义表是n (n≥0) 个元素(子表)a1 , a2 ,…, a n组成的有限序列,一般记作:LS =( a1 , a2 ,…, a n )LS是广义表的名字,n为其表的长度其中a i或者是原子(单个元素)或者是一个广义表,分别称为广义表LS的单元素和子表。
习惯上,用大写字母表示广义表的名称,用小写字母表示单元素。
广义表的定义是一个递归定义,因为在描述广义表时又用到了广义表的概念。
例如:E=( ) E是一个空表,其长度为0。
L=(a, b) L是长度为2的列表,它的两个元素都是原子,因此它是一个线性表。
A=(x, L)=(x, (a, b)) A是长度为2的列表,第一个元素是原子x,第二个元素是子表LB=(A, y)=((x, (a , b)), y) B是长度为2的列表,第一个元素是子表A,第二个元素是原子yC=(A, B)=((x, (a, b)) , ((x, (a, b)), y)) C的长度为2,两个元素都是子表。
D=(a, D)=(a, (a, (a, (...) ) ) ) D的长度为2,第一个元素是原子,第二元素是D自身。
展开后,它是一个无限列表。
一个表的深度是指表展开所含括号的层数,例如,表A的深度为2,表D的深度为∞。
值得注意的是广义表 ( ) 和 (( )) 不同,前者是空表,长度n=0;后者长度n=1,它有一个元素是空表,可分解得到表头和表尾均是空表( )。
广义表的特点:(1)列表可以是递归的,如表D是它本身元素的子表。
(2)列表是多层次的结构,表中的元素可以是子表,子表的元素还可以是子表,……(3)列表可以为其它列表所共享,如上例中,表A和表B是表C的子表。
§6.2 广义表的存储结构由于广义表中的元素可以有不同的结构,单元素或子表,因此难以用顺序存储结构表示,通常采用链式存储结构。
数据结构第4章 串

/*若串s和t相等则返回0;若s>t则返回正数;若s<t则返 回负数*/
{ int i;
for (i=0;i<s.len&&i<t.len;i++)
if (s.ch[i]!=t.ch[i]) return(s.ch[i] - t.ch[i]);
初 始 条 件 : 串 S 存 在 ,1≤pos≤StrLength(S) 且 1≤len≤StrLength(S)-pos+1
操作结果:用Sub返回串S的第pos个字符起长度为len的子串
返回主目录
(11)StrIndex(S,T,pos)
初始条件: 串S和T存在,T是非空串, 1≤pos≤StrLength(S)
return(s.len); }
返回主目录
(7)清空函数
StrClear(SString *s) /*将串s置为空串*/ {
s->len=0; }
返回主目录
(8)连接函数
(1) 连接后串长≤MAXLEN,则直接将B加在A的 后面。 (2) 连接后串长>MAXLEN且LA<MAXLEN,则B 会有部分字符被舍弃。 (3) 连接后串长>MAXLEN且LA=MAXLEN,则B 的全部字符被舍弃(不需连接)。
for (i=s->len + t.len-1;i>=t.len + pos;i--)
s->ch[i]=s->ch[i-t.len];
for (i=0;i<t.len;i++) s->ch[i+pos]=t.ch[i];
s->len=s->len+t.len;
数据结构第4章串.

4.1 串
4.1.1 串的基本概念
串: 由零个或多个字符组成的有限序列。 s = “ a 1a 2 … a n ” s—串名 a1a2… an —串值 ai为字符 ( n≥0)
|s|—串的长度,即串中字符的数目。 空串:零个字符的串,记作φ = “”。空格串 |φ|=0
子串:串中任意个连续的字符组成的子序列 主串:包含子串的串。 例,串 “eij” 是串 “beijing” 的子串, “beijing” 称为主串。 字符在串中的位置:字符在序列中的序号 子串在主串中的位置:子串的第一个字符在主 串中的位置。
(9) 串替换StrReplace(S,i,T) 操作条件: 串S,T存在。 操作结果: 用串T替换串S中自第i个字符开始,长度与T相 等的子串,S的串值改变。
2. 串的存储 顺序串: 串的顺序存储结构。串中的字符被顺 序地存放在一组地址连续的存储单元中。 定长:按预定义的大小为串变量分配一个长度 固定的存储区。 定长顺序串用字符数组描述:
#define MAXSIZE 255 /*假设要处理的串的长度不 会超过255*/ char S[MAXSIZE];
串的实际长度可在这个预定义长度的范围内 随意设定,超过予定义长度的串值则被舍去 (“截断”)
0 C
1 h
2 i
3 n
4 e5 sLeabharlann 6 e \0… …
MAXSIZE-1
串长有两种表示方法: • 用一个整数来存储串的长度。串可以结构描述:
} int StrCat(SeqString *S1, else SeqString *S2) { /* 将 S2 连接到 S1 的末尾构成新串, for(i=0;i<MAXSIZE-S1若S2完全连接到S1末尾则返回 >len;i++) 1,否则返回零*/ S1->s[S1->len+i]=S2->s[i]; { int i; S1->len=MAXSIZE ; if(S1->len+S2return 0; >len<=MAXSIZE) } { }
Chapter04_串_数据结构(C语言版)_严蔚敏_配套课件

Replace (&S, T, V)
初始条件:串S, T和 V 均已存 在,
且 T 是非空串。 操作结果:用V替换主串S中出现
的所有与(模式串)T 相等的不重叠的子串。
例如:
假设 S = ′abcaabcaaabca′,T = ′bca′ 若 V = ′x′, 则经置换后得到
S = ′axaxaax′
• 空串是任意串的子串; • 任意串又是自己的子串
注意: ⑴串值必须用一对单引号括起来,但单引号本身不属
于串; ⑵空串与空白串截然不同,空Байду номын сангаас不包含任何字符。
二、串的抽象数据类型的定义如下:
ADT String { 数据对象: D={ ai |ai∈CharacterSet, i=1,2,...,n, n≥0 } 数据关系:
R1={ < ai-1, ai > | ai-1, ai ∈D, i=2,...,n }
基本操作:
StrAssign (&T, chars)
DestroyString(&S) StrCopy (&T, S) StrLength(S) StrCompare (S, T) Concat (&T, S1, S2) StrEmpty (S)
SubString (&Sub, S, pos, len)
初始条件:
串 S 存在,1≤pos≤StrLength(S) 且0≤len≤StrLength(S)-pos+1。
操作结果:
用 Sub 返回串 S 的第 pos 个字符起 长度为 len 的子串。
子串为“串”中的一个字符子序列
例如: SubString( sub, ′commander′, 4, 3)
数据结构中的串课件
2. 链式存储表示
使用链表来存储串,每个节点存储一个字符。这种 方法适用于较长的串,因为可以动态地分配内存空 间。
串的基本操作
01
02
03
1. 建立串
根据给定的字符串,创建 一个串对象。
2. 插入字符
在串的指定位置插入一个 字符。
3. 删除字符
删除串中指定位置的字符 。
串的基本操作
01
02
03
04
4. 查找字符
查找指定字符在串中的位置。
5. 比较串
比较两个串是否相等。
6. 复制串
将一个串复制到另一个串。
7. 修改串
修改串中指定位置的字符。
02
串的顺序存储结构
Chapter
顺序存储结构的定义
06
串的优化和改进建议
Chapter
使用哈希表优化查找速度
总结词
哈希表能显著提升查找效率
详细描述
哈希表是一种通过计算函数将关键字映射到桶中的数据结构,使得查找操作的 时间复杂度接近O(1)。使用哈希表可以显著提高串的查找速度,特别是在大规 模数据中。
使用动态规划优化插入和删除操作
总结词
动态规划可实现高效插入和删除操作
插入步骤
将插入位置后的字符全部向后移动 一个位置,然后将新字符插入到指 定位置。
时间复杂度
通常为O(n),其中n为字符串的长 度。
串的删除
删除位置
确定要删除的位置,可以是字符 串的开头、结尾或中间任意位置
。
删除步骤
将删除位置后的字符全部向前移 动一个位置,从而覆盖要删除的
广东省汕头市金山中学高中信息技术 信息学竞赛班数据结构专项培训教程 08图
图§8.1 图的基本概念图: 图是数据结构G =(V ,E),其中V 是结点的有穷非空集合,结点的偶对为边,E 是边的集合。
图中的结点又称为顶点。
无向图与有向图:如果图中每条边都是没有方向的,则称为无向图;无向图中的边表示图中顶点的无序对,即(u , v )和(v , u )表示同一条边。
如图8.1.1为一个无向图,它的顶点集和边集分别为: V (G 1)={ 1 , 2 , 3 , 4 , 5 }E (G 1)={(1, 2) , (1, 4) , (2, 3) , (2, 5) , (3, 4) , (3, 5)} 如果图中每条边都是有方向的,则称其为有向图;有向图的边表示图中顶点的有序偶对;在有向图中,箭头表示边的方向。
如图8.1.2为一个有向图,该图的顶点集和边集分别为:V (G 2)={ 1 , 2 , 3 , 4 }E (G 2)={(1, 2) , (1, 3) , (2, 4) , (3, 2) , (4, 3)} 度、入度、出度:在一个有向图中,把以结点V 为终点的弧的数目称为V 的入度;把以结点V 为始点的弧的数目称为V 的出度。
入度和出度之和为该的结点的度。
如图8.1.2中,顶点V 3的入度为2,出度为1,度为3。
路径 、路径长度: 图中从V S 到V P 的一条路径是指一串由顶点所成的连续序列V S , V i1 ,V i2 ,……, V in , V P ,且其中 (V P , V i1) , (V i1 ,V i2) , ……, (V in , V P ) 都是E 上的边。
路径上所包含边的数目称为路径长度。
简单路径、简单回路:如果一条路径的顶点序列中,顶点不重复出现,则称此路径为简单路径。
起点和终点相同的路径称为 回路或环。
除了第一个顶点和最后一个顶点之外,其余顶点不重复出现的回路称为简单回路。
连通图、强连通图:在无向图G 1中,若从顶点V t 到V s 有路径,则称V t 和V s 是连通的。
【精选】数据结构chapter4 串
构
位置:字符在序列中的序号。子串在主串中的位置则
以子串的第一个字符在主串中的位置来表示。
相等:两个串的长度相等,并且对应位置的字符都相等。
空串与 空白串
第4章 串 4.1 串的定义 串的抽象数据类型的定义
数
ADT String{
据 结
数据元素:D={ai| ai∈CharacterSet,记为V, i=1,2,…,n;n≥0} 数据关系:R={<ai,ai+1> | ai, ai+1∈V,i=1,2, …,n-1;n-1≥0 } 基本操作:
sub2= ?
起始位置和子串长度之间存在约束关系!
SubString(sub3,beijing, 7, 2) = ?
sub3 = ?
第4章 串 4.1 串的定义 基本操作:StrIndex (S, pos, T)
数
StrIndex (S, pos, T) 初始条件:主串S和T存在,T是非空串
据
构
(1) StrAssign(S, chars)
(2) StrInsert(S, pos, T)
(3) StrDelete(S, pos, len)
………p106
}ADT String
第4章 串 4.1 串的定义 基本操作:StrInsert (S, pos, T)
数
StrInsert (S, pos, T) 初始条件:串S和T存在,1≤pos≤StrLength(S)+1 。
第4章 串
* 串的模式匹配算法
“子串在主串中的位置”意指子串
中的第一个字符在主串中的位序。
数
据 例如: S = abcaabcaaabc, T = bca
第四章 串教案
第四章串★本章主要讲授内容1、串的定义和基本操作2、串的顺序存储结构3、串的链式存储结构4、模式匹配算法及其改进算法★★课时分配:1、2,两个学时,3两个学时, 4 四个学时,上机6个学时★★★重点、难点:模式匹配及其算法第一节.串的定义和基本运算串是字符串的简称。
它是一种在数据元素的组成上具有一定约束条件的线性表,即要求组成线性表的所有数据元素都是字符,所以,人们经常又这样定义串:串是一个有穷字符序列。
串一般记作:s= "a1a2...an" (n30)其中,s是串的名称,用双引号("")括起来的字符序列是串的值;ai可以是字母、数字或其他字符;串中字符的数目n被称作串的长度。
当n=0时,串中没有任何字符,其串的长度为0,通常被称为空串。
s1= ""s2= " "s1中没有字符,是一个空串;而s2中有两个空格字符,它的长度等于2,它是由空格字符组成的串,一般称此为空格串。
概念:子串、主串:串中任意连续的字符组成的子序列被称为该串的子串。
包含子串的串又被称为该子串的主串。
例如,有下列四个串a,b,c,d:a= "Welcome to Beijing"b= "Welcome"c= "Bei"d= "welcometo"子串的位置:子串在主串中第一次出现的第一个字符的位置。
两个串相等:两个串的长度相等,并且各个对应的字符也都相同。
例如,有下列四个串a,b,c,d:a= "program"b= "Program"c= "pro"d= "program "串的基本操作:(1)创建串StringAssign (s,string_constant)(2)判断串是否为空StringEmpty(s)(3)计算串长度Length(s)(4)串连接Concat(s1,s2)(5)求子串SubStr(s1,s2start,len)(6)串的定位Index(s1,s2)例如1:将s2串插入到串s1的第i个字符后面。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
§4 串 §4.1 串的匹配 子串的定位操作称为串的模式匹配,是各种串处理中最重要的操作。在主字符串S中查找模式字符串P,若在主串中找到等于模式串的子串,称为匹配成功,返回与模式串第一个相等的字符在主串中的序号;若匹配不成功,则返回0。 §4.1.1 串的简单匹配 串的简单匹配,基本思想是:从主串的第一个字符起和模式串的第一个字符比较,若相等,则继续逐个比较后续的字符,否则从主串的第二个字符起再重新和模式串的字符比较。依此类推,直至模式串的每个字符依次和主串中的一个连续的字符序列相等,则为匹配成功...... 【例4-1-1】: 主串:a b a b c a b c a c b a b 匹配串:a b c a c ↓i =3 第一趟匹配: a b a b c a b c a c b a b a b c ↑j =3 ↓i=2 第二趟匹配: a b a b c a b c a c b a b a ↑j=1 ↓i=7 第三趟匹配: a b a b c a b c a c b a b a b c a c ↑j=5 ↓i=4 第四趟匹配: a b a b c a b c a c b a b a ↑j=1 ↓i=5 第五趟匹配: a b a b c a b c a c b a b a ↑j=1 ↓i=11 第六趟匹配: a b a b c a b c a c b a b a b c a c ↑j=6 这种算法易于理解,在某些场合效率也较高。但当主串为'0000000000000000000000000 00000000000000000000000001',模式串为'00000001'时,由于模式串中前7各字符均为'0',主串中前50各字符均为'0',每趟比较都在模式串的最后一个字符出现不等,此时需将指针i回溯到i-6的位置上,并从模式的第一个字符开始重新比较。直到匹配成功,指针i需回溯43次。这经常出现在主串中存在多个子串和模式串"部分匹配"的情况下,例如01串(字符串由0、1组成)。 §4.1.2 串的KMP匹配算法 这种改进的算法是由D.E.Knuth、V.R.Pratt和J.H.Morris三人同时发现的,所以称为KMP算法。 (一)KMP算法的基本思路 KMP算法每当一趟匹配过程中发现字符不等时,不需回溯i指针,而是利用已经得到的"部分匹配"的结果将模式串向右"滑动"尽可能远的一段距离后,继续进行比较。 先回顾简单匹配的算法,从例4-1-1可以看出,在第三趟匹配中,当i=7、j=5字符比较不等时,又从i=4、j=1重新比较。而在i=4和j=1,i=5和j=1,以及i=6和j=1这三次比较都是不必要的。 因为从第三趟部分匹配的结果可以看出,主串中第4、5、6个字符必然是'b'、'c'、'a'(即模式串中第2、3、4个字符)。因为模式串中第一个字符是a,因为它无需和这三个字符进行比较,所以仅需将模式串向右滑动三个字符的位置进行比较。同理,在第一趟匹配中出现字符不等时,仅需将模式串向右移动2个字符的位置继续进行i=3、j=1时的字符比较。由此,整个过程指针i没有回溯,如下所示。 ↓i=3 第一趟匹配:a b a b c a b c a c b a b a b c ↑j=3 ↓i=7 第二趟匹配:a b a b c a b c a c b a b a b c a c ↑j=5 ↓i=11 第三趟匹配:a b a b c a b c a c b a b a b c a c ↑j=6 KMP算法的基本思想是: 在匹配过程中,当 Si≠Pj 时,应在模式串P的开头和主串S紧靠i之前找到相等的最大子串,子串长度为k -1,如图所示:
然后将模式串向右滑动,比较Si和Pk是否相等。 对于KMP算法,需要解决的问题首先是:当匹配过程产生"失配",模式串"向右滑动"可行多远?换句话说,当主串中第i个字符与模式串中第j个字符"失配"(即不相等)时,主串中第i个字符应与模式串中哪个字符再比较?
(二)求证k仅与模式串相关 设主串为S,模式串为P。假设当主串中第i个字符与模式串中第j个字符"失配"时,主串的第i个字符应与模式串的第k个字符继续比较,则模式串中前j个字符必须满足下列关系: 'P1P2......Pk-1'='Si - k+1Si - k+2......Si-1' (1) {匹配串P的前k-1个字符与主串中第i个字符前的k-1个字符相等} 而已经得到"部分匹配"的结果是: 'Pj-k+1Pj-k+2......Pj-1'='Si-k+1Si-k+2......Si-1' (2) {匹配串P第j个字符前的k-1个字符与主串中第i个字符前的k-1个字符相等} 由(1)和(2),可以推出下式: 'P1P2......Pk-1'='Pj-k+1Pj-k+2......Pj-1' 即模式串中前k-1个字符与第j-k+1到j-1个字符相等,即k仅与模式串有关,与主串无关。 (三)next数组 因此,我们可以设next数组,令next[j]=k,则next[j]表明当模式中第j个字符与主串相应字符"失配"时,主串中该字符重新与模式串中进行比较的字符的位置。 Next数组的定义: 0 当 j=1时 next[j]= Max { k | 11 其它情况 【例4.1.2_1】 j 1 2 3 4 5 6 7 8 模式串 next [ j ] a b a a b c a c 0 1 1 2 2 3 1 2
Next数组怎样具体求得,我们这里先放一下,先看看在设了next数组后KMP匹配的算法,这可能将更有利于理解。 (四)KMP算法 匹配可如下进行: ① 指针i和j分别指示主串和模式串中正待比较的字符,令i和j的初值皆为1。 ② 若在匹配过程中si = pi ,则i和j分别增1,否则j再退到下一个next值的位置, 依此类推,直至下列可能: 一种是j退到某个next(next [next [... next[ j ] ] ])值时字符比较相等,则指针各自增1继续进行匹配(模式串滑动); 另一种是j退到next值为0(即模式的第一个字符"失配"),则此时需将模式串继续向右滑动一个位置,从主串的下一个字符si+1起和模式串重新开始匹配。 算法如下: function KMP:integer; ...... {假设已求出next数组} begin i:=1; j:=1; {指针初始化} while (i<=s.length) and (j<=p.length) do {s.length、p.length分别为主串和模式串的长度} if (j = 0) or (s[i]=p[i]) then begin i:=i+1; j:=j+1; {继续下一对字符的比较} end else j:=next[j]; {模式串向右滑动} if j>p.length then KMP:=i-p.length {匹配成功} else KMP:=0; end; (五)求next数组的算法 从上述讨论已知,next数组的值仅与模式串本身有关,而与相匹配的主 串无关,我们可以根据模式串,从分析其定义出发,用递推的方法求得next数组的值。 由定义知: next [1] = 0 设已求得 next [ j ] = k ,求next [ j+1 ] = ? 有两种情况: 1.若Pk = Pj ,则表明在模式串中: 'P1......Pk'='Pj - k+1......Pj' 就是说 next [ j+1 ] = k+1 , 即:next [ j+1 ] = next [ j ] +1 2.若Pk≠Pj,则表明在模式串中: 'P1......Pk'≠'Pj - k+1......Pj' 此时如何处理? procedure next; var i , j , k :integer; begin next [1] := 0; k := 0; for j := 1 to p_length -1 do { p_length为模式串P的长度} begin if (k = 0) or (P[j] = P[k]) then begin
end else begin
end; end; end;
参考答案:① k := k+1; next [j+1] := k; ② repeat k := next [k]; until(k=0)or(P[j]=P[k]); k := k+1; next [j+1] := k;
求next数组程序2: procedure next; var j , k :integer; begin j := 1; k := 0; next[1] := 0; while j < p_length do if(k=0)or(P[j]=P[k]) then begin j := j+1; k := k+1; next[j] := k; end else k := next[k]; end; 另一种求next数组的算法: procedure next; readln (p); next[1]:= 0; for j:=2 to p_length do begin k := j-1; repeat k:=k-1; until copy(p,1,k) = copy(p,j-k,k); next[j] := k+1; end; end;
(六)进一步优化: 前面定义的next函数在某些情况下尚有缺陷,例如: 模式串P='aaaab'和主串S='aaabaaaab'匹配 当i=4,j=4,S[4]≠P[4]时,由next[j]的指示,模式串向右移,S[4]还要与P[3]、P[2]、P[1]继续比较。实际上,因为模式串中第1、2、3个字符和第4个字符都相等,没必要再和S[4]相比较,可将模式串直接向右滑动4个字符,进行i=5、j=1时的比较。 为了克服这种不必要的重复比较,对求next的算法进行改进,其基本思想是:在求得j点的k值后,在判断P[k]和P[j]是否相等,若相等则把nextval[k]值送nextval[j]中,否则把原来的k值存入nextval[j]中。表中的nextval[j]就是改进后的值。 j