第四章串 4.1 串类型定义 4.2 串的表示和实现 4.3 串的模式匹配算法 4.4 串操作应用举例.

Slides:



Advertisements
Similar presentations
1 門市服務丙級技術士 技能檢定介紹 門市服務丙級技術士報告注意事項 證照名稱:門市服務丙級技術士 發照單位:行政院勞工委員會 有效期限:終生有效 考照時間:每年一次,皆為第一梯次 1. 簡章與報名書表發售時間:每年 1 月 2. 報名時間:每年 1 月。 3. 學科考試時間:每年 3.
Advertisements

生源地助学贷款系统还款功能优化说明 评审三局 2015年5月.
二、信用工具和外汇.
为您扬帆,助您远航! 徽商银行特色新产品介绍. 为您扬帆,助您远航! 徽商银行特色新产品介绍.
公务卡使用说明.
教 师:曾晓东 电 话: E_mail: 计算机软件技术基础 教 师:曾晓东 电 话: E_mail:
财务知识培训 杨 秀 玲 2014年10月.
第一章会计技能的内容 1.1会计技能的重要性.
AI人工智慧報告 黑白棋 班級:資工四乙 學號:498G0009 姓名:盧冠妤.
第三章 鏈結串列 Linked List.
第 5 章 流程控制 (一): 條件分支.
補充: Input from a text file
数据结构——树和二叉树 1/96.
第6章 树和二叉树 (Tree & Binary Tree)
(根据所看视频)说一说: 中国戏曲是去是留?. (根据所看视频)说一说: 中国戏曲是去是留?
戏曲大舞台 综合性学习.
第8章 字串與陣列 8-1 字串處理 8-2 一維陣列的處理 8-3 建立多維陣列 8-4 不規則陣列與參數傳遞 8-5 陣列排序與搜尋.
第8章 字元與字串處理 8-1 C語言的字元檢查函數 8-2 C語言的字串 8-3 字串的輸入與輸出 8-4 指標與字串
Linked List Operations
單向鏈結串列 Singly Linked Lists.
第4章 串 串的基本概念和C语言的串函数 串的存储结构 动态数组实现的顺序串 串的模式匹配算法——BF算法 主要知识点.
数据结构 Data Structure 主讲人:王国军,郑瑾 中南大学 中南大学信息院计科系
Zn 模式匹配与KMP算法 Zn
佇列 (Queue).
补充内容 结构体 概述 定义结构体类型和定义结构体变量 结构体变量的引用 结构体变量的初始化 指针与结构体 用typedef定义类型的别名.
程序设计II 第三讲 字符串处理.
零基础学编程(C#) Leo Duan 主讲.
数据结构 第4章 串.
计算概论 第十八讲 C语言高级编程 结构与习题课 北京大学信息学院.
第三章 C++中的C 面向对象程序设计(C++).
Chap 8 指针 8.1 寻找保险箱密码 8.2 角色互换 8.3 冒泡排序 8.4 电码加密 8.5 任意个整数求和*
线性表小结 元素之间的线性关系 顺序表 顺序表:元素相邻存储 单链表:后继指针链接 一维数组 给定下标随机存取
第3章 栈和队列(二) 1/.
数据结构——串 1/15.
第四章 串和数组(一) 1/.
第4章 程序控制结构与算法基础.
串和数组.
第 3 讲 线性表(一).
第三章 栈与队列 £3.1 栈 £3.3 队列 £3.2 栈的应用举例 £3.1.1 栈的定义 £3.1.2 栈的顺序存储结构
第3章 栈和队列(一).
第三章 栈和队列.
数据结构 Data Structure 中南大学 主讲人:王国军,郑瑾 中南大学信息院计科系
第二章 线性表.
数 据 结 构 Ch.4 串 计 算 机 学 院 肖明军
陈海明 副教授 信息学院 计算机系 电子信息类非计算机专业选修课 程序设计实践 陈海明 副教授 信息学院 计算机系
THE C PROGRAMMING LANGUAGE
4.1 串的抽象数据类型的定义 4.2 串的表示和实现 4.3 串的模式匹配算法.
第4章 常量和变量 常量和变量都是程序中预留的用于保存数据的内存空间。常量的值在程序运行过程中始终不会发生变化。而变量的值在程序的运行过程中是可以变化的。在Fortran语言中,有五种基本的数据类型可供使用。他们分别是整型(INTEGER)、实型(REAL)、复型(COMPLEX)、字符型(CHARACTER)和逻辑型(LOGICAL)。按用途,又可以分数值型、字符型和逻辑型三种。相应的常量和变量也可以分为这三种。本章将按照用途介绍常量和变量的基本概念。
6.6 Huffman树及其应用 王 玲.
第四章 串.
編譯程式設計 期末專題說明 V1.1 May 2004.
王玲 第 2 章 线性表 王玲 2019/2/25.
第五章 串和数组 5.1 串的定义和操作 5.2 串的表示和实现 5.3 字符串应用 5.4 字符串匹配算法 5.5 数组
第四章 串.
7.1 广义表的概念 广义表是n(n≥0)个数据元素组成的序列,其中每个数据元素或是单个数据元素(简称原子),或仍然是一个广义表 。
软件测试 (四)静态测试与动态测试.
第六章 树和二叉树 £6.1 树 £6.2 二叉树 £6. 3 二叉树的存储结构 £6.4 二叉树的遍历与线索化 £6.1.1 树的定义
第五章 串和数组 5.1 串的定义和操作 5.2 串的表示和实现 5.3 字符串应用 5.4 字符串匹配算法 5.5 数组
第四章 串和数组 4.1 串的定义* 4.2 串的表示和实现* 4.3 数组 4.4 数组的压缩.
本教學投影片係屬教科書著作之延伸,亦受著作權法之保護。
字符串 (String) 字符串是 n (  0 ) 个字符的有限序列, 记作 S = “c1c2c3…cn” 其中,S 是串名字
第4章 数 组.
<编程达人入门课程> 本节内容 为什么要使用变量? 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
第 六 讲 栈和队列(一).
第四章 串 £4.1 串的定义 £4.2 串的顺序存储结构 £4.3 串的链式存储结构 £4.4 串的应用—文本编辑
#include <iostream.h>
字符串模式匹配- KMP 主讲:朱佳 博士 华南师范大学计算机学院.
第1章 数据结构基础概论 本章主要介绍以下内容 数据结构研究的主要内容 数据结构中涉及的基本概念 算法的概念、描述方法以及评价标准.
Oop7 字串 String.
本节内容 1.二叉排序树的定义 2.二叉排序树的查找操作 3.二叉排序树的插入操作 4.二叉排序树的删除操作 5.二叉排序树的总结
Presentation transcript:

第四章串 4.1 串类型定义 4.2 串的表示和实现 4.3 串的模式匹配算法 4.4 串操作应用举例

4.1 串类型的定义 串是由零个或多个字符组成的有限序列 一般记作:S= a1a2…an 其中S是串名, 单引号括起来的字符序列是串的值 N为串长度,零个字符的串为空串 串中任意个连续字符构成的子序列为子串 字符在序列中的序号为串的位置

例如:a= BEI b= BEIJING c= JING d=  e=   a的长度为3,c是b的子串, c在b中的位置为4 注意串一般由单引号括起来表示, 区别于C语言中用双引号括起来表示字符串 在利用C语言实现时注意编程时语句格式

例如:a= BEI b= BEIJING c= JING d=  e=   注意空串和空格串 由一个或多个空格构成的串为空格串 两个单引号中间无任何字符时表示空串 一般用Ф表示 空串是任意串的子串

基本操作: StrAssign (&T, chars) DestroyString(&S) StrLength(S) StrCopy (&T, S) Concat (&T, S1, S2) StrCompare (S, T) StrEmpty (S) ClearString (&S) SubString (&Sub, S, pos, len) Index (S, T, pos) Replace (&S, T, V) StrInsert (&S, pos, T) StrDelete (&S, pos, len)

StrAssign (&T, chars) 初始条件:chars 是字符串常量。 操作结果:把 chars 赋为 T 的值。 StrCopy (&T, S) 初始条件:串 S 存在。 操作结果:由串 S 复制得串 T。 DestroyString (&S) 初始条件:串 S 存在。 操作结果:串 S 被销毁。

StrEmpty (S) 初始条件:串S存在。 操作结果:若 S 为空串,则返回TRUE, 否则返回 FALSE。   表示空串,空串的长度为零。

例如:StrCompare(data, state) < 0 StrCompare(cat, case) > 0 StrCompare (S, T) 初始条件:串 S 和 T 存在。 操作结果:若S  T,则返回值  0; 若S  T,则返回值  0; 若S  T,则返回值  0。 例如:StrCompare(data, state) < 0 StrCompare(cat, case) > 0

StrLength (S) 初始条件:串 S 存在。 操作结果:返回 S 的元素个数,称为串的长度。 Concat (&T, S1, S2) 初始条件:串 S1 和 S2 存在。 操作结果:用 T 返回由 S1 和 S2 联接而成的新串。 例如: Concate( T, man, kind) 求得 T = mankind

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) 求得 sub = man ; SubString( sub, commander, 1, 9) 求得 sub = commander; SubString( sub, commander, 9, 1) 求得 sub = r;

SubString (&Sub, S, pos, len) 初始条件:串 S 存在,1≤pos≤StrLength(S) 且0≤len≤StrLength(S)-pos+1。 操作结果:用 Sub 返回串 S 的第 pos 个字符起 长度为 len 的子串。 SubString( sub, commander, 4, 0) 求得 sub =  ;

Index (S, T, pos) 初始条件:串S和T存在,T是非空串, 1≤pos≤StrLength(S)。 操作结果: 若主串 S 中存在和串 T 值相同 的子串, 则返回它在主串 S 中第pos个 字符之后第一次出现的位置; 否则函数值为0。 假设 S = abcaabcaaabc, T = bca 2 Index(S, T, 1) Index(S, T, 3) 6 Index(S, T, 8)

StrInsert (&S, pos, T) 初始条件:串S和T存在, 1≤pos≤StrLength(S)+1。 操作结果:在串S的第pos个字符之前 插入串T。 例如:S = chater,T = rac, 则执行 StrInsert(S, 4, T)之后得到 S = character

StrDelete (&S, pos, len) 初始条件:串S存在 1≤pos≤StrLength(S)-len+1。 操作结果:从串S中删除第pos个字符 起长度为len的子串。 ClearString (&S) 初始条件:串S存在。 操作结果:将S清为空串。

strcat(str1, str2) 串联接函数; strcpy(str1, str2, k) 串复制函数; 对于串的基本操作集可以有不同的定义方法,在使用高级程序设计语言中的串类型时,应以该语言的参考手册为准。 例如:C语言函数库中提供下列串处理函数: gets(str) 输入一个串; puts(str) 输出一个串; strcat(str1, str2) 串联接函数; strcpy(str1, str2, k) 串复制函数; strcmp(str1, str2) 串比较函数; strlen(str) 求串长函数;

串操作定义的13种操作中, 串赋值StrAssign、串复制Strcopy、 串比较StrCompare、求串长StrLength、 串联接Concat以及求子串SubString 等六种操作构成串类型的最小操作子集。 即:这些操作不可能利用其他串操作来实现, 反之,其他串操作(除串清除ClearString和串 销毁DestroyString外)可在这个最小操作子 集上实现。

例如,可利用串比较、求串长和求子串等操作实现定位函数Index(S,T,pos)。 Index (S, T, pos) 初始条件:串S和T存在,T是非空串, 1≤pos≤StrLength(S)。 操作结果: 若主串 S 中存在和串 T 值相同 的子串, 则返回它在主串 S 中第pos个 字符之后第一次出现的位置; 否则函数值为0。

? i 算法的基本思想为: 从pos位置开始在S中取子串 X = SubString(S, i, StrLength(T)), StrCompare( X , T ) i S 串 pos n-m+1 T 串 T 串 若主串S中第pos个字符之后存在与 T相等的子串,则返回第一个这样的子串在S中的位置,否则返回0

int Index (String S, String T, int pos) { } return 0; if (pos <= 0) return ERROR; n = StrLength(S); m = StrLength(T); i = pos; while ( i <= n-m+1) { } SubString (sub, S, i, m); if (StrCompare(sub,T) != 0) ++i ; else return i ;

作业 实现串的替换操作,replace函数

串的逻辑结构和线性表极为相似,区别 仅在于串的数据对象约束为字符集。 串的基本操作和线性表有很大差别。 在线性表的基本操作中,大多以“单个元素”作为操作对象; 在串的基本操作中,通常以“串的整体”作为操作对象。

4.2 串的表示和实现 一、串的定长顺序存储表示 二、串的堆分配存储表示 三、串的块链存储表示

一、串的定长顺序存储表示 用一组连续的预定义大小的内存单元中存储字符串序列,串的长度须在预定义长度范围内,超出预定义长度则超出部分被舍弃,称为截断 表示串长度时有两种方式: 一种是将串长度存入下标为0的单元中 另外一种是在串的末尾加上’\0’结束标志 此时串长度是隐含的

下面给出串的定义形式 #define MAXSTRLEN 255 // 用户可在255以内定义最大串长 typedef unsigned char Sstring[MAXSTRLEN + 1]; 如此定义后Sstring为串类型 Sstring s;表示s中最多可存储255个字符, 其中s[ 0]单元存放串的长度

语句形式 T[ 1..S1[0] ] = S1[1..S1[0]]; S1[0]中存放字符串长度 作用:将s1中的字符串复制给t

下面以串连接和求子串函数的实现说明串的使用 假设S1和S2是Sstring类型变量 串T由S1串连接S2得到 实现方法: 将S1复制到T的前半段,然后将S2复制到T的后半段,若超出最大长度则进行截断

Status Concat(SString S1, SString S2, SString &T) { return uncut; } // Concat if (S1[0]+S2[0] <= MAXSTRLEN) { T[ 1..S1[0] ] = S1[1..S1[0]]; T[ S1[0]+1..S1[0]+S2[0] ] = S2[ 1.. S2[0] ]; T[0] = S1[0]+S2[0] ; uncut = FALSE; }

Status Concat(SString S1, SString S2, SString &T) { return uncut; } // Concat if (S1[0]+S2[0] <= MAXSTRLEN) { … } else if (S1[0] <MAXSTRSIZE) { T[ 1..S1[0] ] = S1[1..S1[0]]; T[S1[0]+1..MAXSTRLEN] = S2[1..MAXSTRLEN-S1[0]]; T[0] = MAXSTRLEN; }

Status Concat(SString S1, SString S2, SString &T) { return uncut; } // Concat if (S1[0]+S2[0] <= MAXSTRLEN) { … } else if (S1[0] <MAXSTRSIZE) { else { T[0..MAXSTRLEN] = S1[0..MAXSTRLEN]; T[0] == S1[0] == MAXSTRLEN }

二、串的堆分配存储表示 串的顺序存储表示有何缺点 串的操作时可能会出现截断 当串长度小于存储区长度时会浪费内存空间 堆分配存储表示是利用malloc和free函数来管理一段称为“堆”的内存区域,需要时则分配,使用完毕后则释放。 通过malloc分配的内存可以利用内存地址使用

typedef struct { char *ch; int length; } HString; HString S; B C D E F G H A I J S 10 S.ch = (char *) malloc (10 * sizeof(char) ) S.Length = 10;

串的连接操作: 假设有串S1和串S2连接成串T B C D E A S1 5 F G H I J S1 5 A B C D E F G H 10 特别注意:若T原来有内存则须先释放原有内存

Status Concat(HString &T, HString S1, HString S2) { if ( T.ch ) free(T.ch); T.ch = (char*) malloc((S1.length+S2.length)*sizeof(char)); T.ch[0..S1.length-1] = S1.ch[0..S1.length-1]; T.ch[S1.length..T.length-1] = S2.ch[0..S2.length-1]; T.length = S1.length + S2.length; return OK; }

Status StrAssign(HString &T,char *chars){ 串的其他操作函数 Status StrAssign(HString &T,char *chars){ } if ( T.ch ) free (T); for( i=0 , c= chars; c ; ++i, ++c;) ; if ( !i ) { T.ch=NULL ; T.length=0; } else { T.ch=(char*)malloc(i*sizeof(char)); T.ch[0..i-1]= chars[0..i-1]; T.length=i; } 产生一个串T,内容为chars所指字符串

L L 三、串的块链存储表示 B A E ^ C D 存储密度 = 数据元素所占存储位 实际分配的存储位 C A B D E F G H I

#define CHUNKSIZE 80 // 可由用户定义块大小 typedef struct Chunk { // 结点结构 char ch[CUNKSIZE]; struct Chunk *next; } Chunk; typedef struct { // 串的链表结构 Chunk *head, *tail; // 串的头和尾指针 int curlen; // 串的当前长度 } LString;

实际应用时, 可以根据问题所需来设置结点的大小。 例如: 在编辑系统中,整个文本编辑区可以看成是一个串,每一行是一个子串,构成一个结点。即: 同一行的串用定长结构(80个字符), 行和行之间用指针相联接。

4.3 串的模式匹配算法 这是串的一种重要操作,很多软件,若有“编辑”菜单项的话,则其中必有“查找”子菜单项。

首先,回忆一下串匹配(查找)的定义: INDEX (S, T, pos) 初始条件:串S和T存在,T是非空串, 1≤pos≤StrLength(S)。 操作结果:若主串S中存在和串T值相 同的子串返回它在主串S中第pos个字符之后第一次出现的位置;否则函数 值为0。

以定长顺序结构表示串时的算法。 一、简单算法 二、KMP算法

串的匹配算法 B A C \0 B A C \0

B A C \0 B A C \0

B A C \0 B A C \0

B A C \0 B A C \0

B A C \0 B A C \0

S[0]中存放S串的长度 一、简单算法 int Index(SString S, SString T, int pos) { i = pos; j = 1; while (i <= S[0] && j <= T[0]) { if ( S[i] == T[j] ) { ++i; ++j; } else { i = (i-j+1)+1; j = 1; } } if (j > T[0]) return i-T[0]; else return 0;

二、KMP 算法 第一趟比较 a b a b c a b c a c b a b i=1 a b c a c j=1

二、KMP 算法 第一趟比较 a b a b c a b c a c b a b i=2 a b c a c j=2

二、KMP 算法 第一趟比较 a b a b c a b c a c b a b i=3 a b c a c j=3 当比较发现模式中的第j字符与主串中的第i个字符不相等时,再次比较时不从头开始,而是让模式串向右滑动,再次进行比较

二、KMP 算法 第二趟比较 a b c i=3 a b c j=1 当比较发现模式中的第j字符与主串中的第i个字符不相等时,再次比较时不从头开始,而是让模式串向右滑动,再次进行比较。 滑动多少个字符?这是关键问题

二、KMP 算法 第二趟比较 a b c i=4 a b c j=2

二、KMP 算法 第二趟比较 a b c i=5 a b c j=3

二、KMP 算法 第二趟比较 a b c i=6 a b c j=4

二、KMP 算法 第二趟比较 a b c i=7 a b c j=5 当比较发现模式中的第j字符与主串中的第i个字符不相等时,再次比较时不从头开始,而是让模式串向右滑动,再次进行比较。 滑动多少个字符?这是关键问题

二、KMP 算法 第三趟比较 a b c i=7 a b c j=2 当比较发现模式中的第j字符与主串中的第i个字符不相等时,再次比较时不从头开始,而是让模式串向右滑动,再次进行比较。 滑动多少个字符?这是关键问题

二、KMP 算法 第三趟比较 a b c i=8 a b c j=3

二、KMP 算法 第三趟比较 a b c i=9 a b c j=4

二、KMP 算法 第三趟比较 i=10 j=5 匹配成功 关键问题: 当主串第i字符与模式中的第j字符不匹配时 a b c i=10 a b c j=5 匹配成功 关键问题: 当主串第i字符与模式中的第j字符不匹配时 第i字符应与模式中的哪个字符进行下一步比较

二、KMP 算法 i=7 j=5 关键问题: 当主串第i字符与模式中的第j字符不匹配时 第i字符应与模式中的哪个字符进行下一步比较 a b c i=7 a b c j=5 关键问题: 当主串第i字符与模式中的第j字符不匹配时 第i字符应与模式中的哪个字符进行下一步比较

二、KMP 算法 i=7 j=5 假设: 当主串第i字符与模式中的第j字符不匹配时 第i字符应与模式中的第k字符进行下一步比较 a b c i=7 a b c j=5 假设: 当主串第i字符与模式中的第j字符不匹配时 第i字符应与模式中的第k字符进行下一步比较 此时k值取多少?

二、KMP 算法 i=7 j=5 假设: 当主串第i字符与模式中的第j字符不匹配时 第i字符应与模式中的第k字符进行下一步比较 a b c

二、KMP 算法 i=7 j=5 第k字符 k=2 假设: 当主串第i字符与模式中的第j字符不匹配时 a b c i=7 a b c j=5 第k字符 k=2 假设: 当主串第i字符与模式中的第j字符不匹配时 第i字符应与模式中的第k字符进行下一步比较 令 next[j]=k 表示当第j字符与第i字符不匹配时,应该从模式中的第k字符开始与第i字符再次比较

假设: 当主串第i字符与模式中的第j字符不匹配时 第i字符应与模式中的第k字符进行下一步比较 令 next[j]=k 表示当第j字符与第i字符不匹配时,应该从模式中的第k字符开始再次比较 next[1]= 0 next[2]= 1 next[3]=? … next[j]=?

第k字符前的k-1个字符与第j字符前的k-1个字符相等 a b c i=7 a b c j=5 a b c i=7 a b c j=5 第k字符 k=2 得到结论: 第k字符前的k-1个字符与第j字符前的k-1个字符相等

主串中的第i个字符与模式中的第j个字符不相等时,将模式串向右滑动,使得第i字符与模式中的第k字符进行下一次比较。 另一个模式匹配的例子 a b c c a b c 主串中的第i个字符与模式中的第j个字符不相等时,将模式串向右滑动,使得第i字符与模式中的第k字符进行下一次比较。

主串中的第i个字符与模式中的第j个字符不相等时,将模式串向右滑动,使得第i字符与模式中的第k字符进行下一次比较。 另一个模式匹配的例子 a b c a c a b c 主串中的第i个字符与模式中的第j个字符不相等时,将模式串向右滑动,使得第i字符与模式中的第k字符进行下一次比较。 此时为什么k值取为3?

主串中的第i个字符与模式中的第j个字符不相等时,将模式串向右滑动,使得第i字符与模式中的第k字符进行下一次比较。 另一个模式匹配的例子 a b c a a c a b c 主串中的第i个字符与模式中的第j个字符不相等时,将模式串向右滑动,使得第i字符与模式中的第k字符进行下一次比较。 此时为什么k值取为3?

主串中的第i个字符与模式中的第j个字符不相等时,将模式串向右滑动,使得第i字符与模式中的第k字符进行下一次比较。 另一个模式匹配的例子 a b c a a c a b c 主串中的第i个字符与模式中的第j个字符不相等时,将模式串向右滑动,使得第i字符与模式中的第k字符进行下一次比较。 此时为什么k值取为3?

第k字符前的k-1个字符与第j字符前的k-1个字符相等 a b c c a b c i a b c c a b c j k 第k字符前的k-1个字符与第j字符前的k-1个字符相等 令next[j]=k 表示第j个字符与第i个字符不相等时使第i字符与第k字符进行下一次比较

第k字符前的k-1个字符与第j字符前的k-1个字符相等 若第k个字符与第j个字符相等,则next[j+1]值为k+1 next[j]=k 表示当第j字符与第i字符不匹配时应该从模式中的第k字符开始与第i字符再次比较, next[j+1]如何计算? …………… ………………… 模式 j j+1 k-1 k k-1 k k 第k字符前的k-1个字符与第j字符前的k-1个字符相等 若第k个字符与第j个字符相等,则next[j+1]值为k+1 next[j+1] = next[j]+1 推导出:next[j+1] =??

若不存在k’,则 next[j+1] =1 k j j+1 …………… ……………… k’ k’ …………… ……………… k’ k’+1 k’ 第k字符前的k-1个字符与第j字符前的k-1个字符相等 若第k个字符与第j个字符不相等, next[j+1] = k’+1 若不存在k’,则 next[j+1] =1

规定Next[1] = 0 表示模式中第1个字符与主串第i字符不相等时,无需j值回退,直接比较i+1字符即可 next[j]=k 表示当第j字符与第i字符不匹配时应该从模式中的第k字符开始与第i字符再次比较 规定Next[1] = 0 表示模式中第1个字符与主串第i字符不相等时,无需j值回退,直接比较i+1字符即可 当不存在 第j字符前的k-1个字符与 1到k-1 的字符序列相等时 表示j需要回退至模式的第一个字符 1 2 3 4 5 6 7 8 a b a a b c a c Next[j] 0 1 1 2 2 3 1 2

1 2 3 4 5 6 7 8 9 a b a b a a b a b Next[j] 0 1 1 2 3 4 2 3 4

Next的算法 i=1; nextval[1]=0; j=0; While ( i< T[0] ) { if( j= =0 || T[i]= =T[j] ) { i++; j++; next[i] = j; else j = next[j]; } i= 1 1 2 3 4 5 6 7 8 j= a b a a b c a c Next[j]

1 Next的算法 i=1; nextval[1]=0; j=0; While ( i< T[0] ) { if( j= =0 || T[i]= =T[j] ) { i++; j++; next[i] = j; else j = next[j]; } i= 2 1 2 3 4 5 6 7 8 j= 1 a b a a b c a c Next[j] 1

1 Next的算法 i=1; nextval[1]=0; j=0; While ( i< T[0] ) { if( j= =0 || T[i]= =T[j] ) { i++; j++; next[i] = j; else j = next[j]; } i= 2 1 2 3 4 5 6 7 8 j= 1 a b a a b c a c Next[j] 1

1 1 Next的算法 i=1; nextval[1]=0; j=0; While ( i< T[0] ) { if( j= =0 || T[i]= =T[j] ) { i++; j++; next[i] = j; else j = next[j]; } i= 3 2 1 2 3 4 5 6 7 8 j= 1 a b a a b c a c Next[j] 1 1

1 1 Next的算法 i=1; nextval[1]=0; j=0; While ( i< T[0] ) { if( j= =0 || T[i]= =T[j] ) { i++; j++; next[i] = j; else j = next[j]; } i= 3 1 2 3 4 5 6 7 8 j= 1 a b a a b c a c Next[j] 1 1

1 1 2 Next的算法 i=1; nextval[1]=0; j=0; While ( i< T[0] ) { if( j= =0 || T[i]= =T[j] ) { i++; j++; next[i] = j; else j = next[j]; } i= 4 1 2 3 4 5 6 7 8 j= 2 a b a a b c a c Next[j] 1 1 2

1 1 2 Next的算法 i=1; nextval[1]=0; j=0; While ( i< T[0] ) { if( j= =0 || T[i]= =T[j] ) { i++; j++; next[i] = j; else j = next[j]; } i= 4 1 2 3 4 5 6 7 8 j= 1 a b a a b c a c Next[j] 1 1 2

1 1 2 2 Next的算法 i=1; nextval[1]=0; j=0; While ( i< T[0] ) { if( j= =0 || T[i]= =T[j] ) { i++; j++; next[i] = j; else j = next[j]; } i= 5 1 2 3 4 5 6 7 8 j= 2 a b a a b c a c Next[j] 1 1 2 2

1 1 2 2 3 Next的算法 i=1; nextval[1]=0; j=0; While ( i< T[0] ) { if( j= =0 || T[i]= =T[j] ) { i++; j++; next[i] = j; else j = next[j]; } i= 6 1 2 3 4 5 6 7 8 j= 3 a b a a b c a c Next[j] 1 1 2 2 3

1 1 2 2 3 Next的算法 i=1; nextval[1]=0; j=0; While ( i< T[0] ) { if( j= =0 || T[i]= =T[j] ) { i++; j++; next[i] = j; else j = next[j]; } i= 6 1 2 3 4 5 6 7 8 j= 1 a b a a b c a c Next[j] 1 1 2 2 3

1 1 2 2 3 Next的算法 i=1; nextval[1]=0; j=0; While ( i< T[0] ) { if( j= =0 || T[i]= =T[j] ) { i++; j++; next[i] = j; else j = next[j]; } i= 6 1 2 3 4 5 6 7 8 j= a b a a b c a c Next[j] 1 1 2 2 3

1 1 2 2 3 1 Next的算法 i=1; nextval[1]=0; j=0; While ( i< T[0] ) { if( j= =0 || T[i]= =T[j] ) { i++; j++; next[i] = j; else j = next[j]; } i= 7 1 2 3 4 5 6 7 8 j= 1 a b a a b c a c Next[j] 1 1 2 2 3 1

1 1 2 2 3 1 2 Next的算法 i=1; nextval[1]=0; j=0; While ( i< T[0] ) { if( j= =0 || T[i]= =T[j] ) { i++; j++; next[i] = j; else j = next[j]; } i= 8 1 2 3 4 5 6 7 8 j= 2 a b a a b c a c Next[j] 1 1 2 2 3 1 2

Next中存在的问题 a b i=1 a b j=1 1 2 3 4 5 a a a a b Next[j] 0 1 2 3 4

Next中存在的问题 a b i=4 a b j=4 1 2 3 4 5 a a a a b Next[j] 0 1 2 3 4

Next中存在的问题 a b i=4 a b j=3 1 2 3 4 5 a a a a b Next[j] 0 1 2 3 4

Next中存在的问题 a b i=4 a b j=2 1 2 3 4 5 a a a a b Next[j] 0 1 2 3 4

Next中存在的问题 a b i=4 a b j=1 1 2 3 4 5 a a a a b Next[j] 0 1 2 3 4

Next中存在的问题 a b i=5 a b j=1 1 2 3 4 5 a a a a b Next[j] 0 1 2 3 4

Next中存在的问题 a b i=9 a b j=5 1 2 3 4 5 a a a a b Next[j] 0 1 2 3 4

第j字符不匹配时,由于模式中第j字符前的字符一样,所以无需判断j之前的字符是否与主串的第i字符是否匹配 1 2 3 4 5 Next中存在的问题 a b i=9 a b j=5 第j字符不匹配时,由于模式中第j字符前的字符一样,所以无需判断j之前的字符是否与主串的第i字符是否匹配 1 2 3 4 5 a a a a b Next[j] 0 1 2 3 4

Next的修正算法 第j字符不匹配时,由于模式中第j字符前字符一样,所以无需判断j之前的字符是否与主串的第i字符是否匹配 i=1; nextval[1]=0; j=0; While ( i< T[0] ) { if( j==0 || T[i]==T[j] ) { i++; j++; if( T[i]!=T[j] ) nextval[i] = j; else nextval[i] = nextval[j]; } else j=nextval[j];

请详细了解KMP模式匹配算法中 next值得计算过程!

4.4 串操作的应用举例 本节内容作为课下作业 建立一个文件A内存常用词 另一个文件B存一篇文章的摘要 编写程序从文件B中读取内容并分析出哪些是关键词,输出显示出所有关键词

本章学习要点 1. 熟悉串的七种基本操作的定义,并能利用这些基本操作来实现串的其它各种操作的方法。 2. 熟练掌握在串的定长顺序存储结构上实现串的各种操作的方法。 3. 了解串的堆存储结构以及在其上实现串操作的基本方法。

令 next[j]=k 表示当第j字符与第i字符不匹配时,应该从模式中的第k字符开始再次比较 c b a i= 2 1 a b c j= 1 1 令 next[j]=k 表示当第j字符与第i字符不匹配时,应该从模式中的第k字符开始再次比较 j=1时,规定next[1]的值为0 模式中的第1个字符与主串中的第i个字符不相等时,模式不滑动,主串i加1,模式中的j仍是1 其他next[j]如何求得?

令 next[j]=k 表示当第j字符与第i字符不匹配时,应该从模式中的第k字符开始再次比较 c b a i= 3 2 a b c j= 1 1 令 next[j]=k 表示当第j字符与第i字符不匹配时,应该从模式中的第k字符开始再次比较 j=1时,规定next[1]的值为0 模式中的第1个字符与主串中的第i个字符不相等时,模式不滑动,主串i加1,模式中的j仍是1 其他next[j]如何求得?

令 next[j]=k 表示当第j字符与第i字符不匹配时,应该从模式中的第k字符开始再次比较 c b a i= 4 3 a b c j= 2 1 令 next[j]=k 表示当第j字符与第i字符不匹配时,应该从模式中的第k字符开始再次比较 j=1时,规定next[1]的值为0 模式中的第1个字符与主串中的第i个字符不相等时,模式不滑动,主串i加1,模式中的j仍是1 其他next[j]如何求得?

令 next[j]=k 表示当第j字符与第i字符不匹配时,应该从模式中的第k字符开始再次比较 c b a i= 5 4 a b c j= 3 2 令 next[j]=k 表示当第j字符与第i字符不匹配时,应该从模式中的第k字符开始再次比较 j=1时,规定next[1]的值为0 模式中的第1个字符与主串中的第i个字符不相等时,模式不滑动,主串i加1,模式中的j仍是1 其他next[j]如何求得?