`
bulote
  • 浏览: 1354119 次
文章分类
社区版块
存档分类
最新评论

优秀课件笔记之串

 
阅读更多
第四章 串
 4.1 串类型的定义
 4.2 串的表示和实现
4.2.1 定长顺序存储表示
4.2.2 堆分配存储表示
4.2.3 串的块链存储表示
 4.3 串的模式匹配算法
一、串及其基本概念
串的定义:串(String)是零个或多个字符组成的有限序列。
一般记作S=“
a1a2a3…
an”
,其中S是串名,双引号括起来的字符
序列是串值;ai(1≦i≦n)可以是字母、数字或其它字符。
串的长度:串中所包含的字符个数称为该串的长度。
空串:长度为零的串称为空串(Empty String) ,它不包含任何
字符。
空格串:将仅由一个或多个空格组成的串称为空格串(Blank
String)。注意:空串和空格串的不同,例如“

和“”
分别表
示长度为1的空格串和长度为0的空串。
4.1 串类型的定义
子串与主串:串中任意个连续字符组成的子序列称为该串的子
串,包含子串的串相应地称为主串。通常将子串在主串中首
次出现时的该子串的首字符对应的主串中的序号,定义为子
串在主串中的位置。
例如,设A=“
This is a string ”
B=“
is”
则B是A的子串,A
为主串。B在A中出现了两次,其中首次出现所对应的主串位
置是3。因此,称B在A中的位置为3。
相等:当且仅当两个串的长度相等,并且每个对应位置的字符
都相等时,称两个串相等。
例如,A=“
BEIJING”
B=“
BEIJING”
,则串A与串B相等。
串常量和串变量:串常量和整常数、实常数一样,在程序中只
能被引用但不能改变其值,即只能读不能写。串变量的值在
程序中可以改变,即可以读也可以写。
4.1 串类型的定义
二、串的抽象数据定义
串的抽象数据类型定义见教材P71
三、串的基本操作
对于串的基本操作,许多高级语言均提供了相应的运算或
标准库函数来实现。下面仅介绍几种在C语言中常用的串运算。
定义下列几个变量:
char s1[20]= “
dirtreeformat ”
,
s2[20]=“
file.txt ”
;
char s3[30], *p;
int result;
4.1 串类型的定义
1 求串长(length)
int strlen(char *s); //求串的长度
例如:printf(“
%d”
,strlen(s1)); 输出13
2 串复制(copy)
char *strcpy(char *to,char *from);
该函数将串from复制到串to中,并且返回一个指向串to的开
始处的指针。
例如:strcpy(s3,s1); //s3= “
dirtreeformat ”
3 联接(concatenation)
char strcat(char *to,char *from)
该函数将串from复制到串to的末尾,并且返回一个指向串to
的开始处的指针。
例如:strcat(s3 , “
/”
)
strcat(s3,s2); //s3= “
dirtreeformat/file.txt ”
4.1 串类型的定义
4 串比较(compare)
int strcmp(char *s1,char *s2);
该函数比较串s1和串s2的大小,当返回值小于0,等于0或大
于0时分别表示s1<s2,s1=s2或s1>s2
例如:result=strcmp(“
baker”
,“
Baker”
); //result>0
result=strcmp( “
12”
,“
12”
); //result=0
result= strcmp(“
Jos”
,“
Joseph”
); //result<0
5 字符定位(index)
char strchr(char *s,char c);
该函数是找c在字符串中第一次出现的位置,若找到则返回该
位置,否则返回NULL。
例如:p=strchr(s2, “
.”
); //p指向“
file”
之后的位置
if(p) strcpy(p, “
.cpp”
); //s2= “
file.cpp ”
4.1 串类型的定义
2
Page 2
例1、求子串
求子串的过程即为复制字符序列的过程,将串S中的第pos个
字符开始长度为len的字符复制到串T中。
void substr(char *sub,char *s,int pos,int len)
{ if( pos<0 || pos>strlen(s)-1 || len<0 )
error( “
parameter error ”
);
strncpy(sub,s+pos,len );
}
例2、串的定位index(char *s,char *t,int pos)
求串T在主串S中第pos个字符之后的位置。方法:从主串S的第
pos个字符开始,取长度和串T相等的子串和T比较,若相等,则求
得函数值为pos。否则子串位置增1继续与T比较,直至找到与T相
等的子串或确定S中不存在和串T相等的子串为止。
4.1 串类型的定义
int index(char *s, char *t, int pos)
{ if( pos>0 )
{ n = strlen( s );
m = strlen( t );
i = pos;
while( i<n-m+1 )
{ substr( sub, s, i, m );
if( strcmp( sub, t ) != 0 )
++i;
else return( i );
}
}
return( 0 );
}
4.1 串类型的定义
定长顺序存储表示,也称为静态存储分配的顺应表。它是用一组
连续的存储单元来存放串中的字符序列。所谓定长顺序存储结构,
是直接使用定长的字符数组来定义,数组的上界预先给出:
#define maxstrlen 255
typedef char SString[maxstrlen ]; // 0分量存放串长
4.2 串的表现和实现
4.2.1 定长顺序存储表示
Status SubString( SString &Sub, SString S, int pos, int len )
{ if( pos < 1 || pos > S[0] || len < 0 || len > S[0]-pos+1 )
return ERROR;
Sub[1..len] = S[pos..pos+len-1];
Sub[0] = len;
retrun OK;
}
Status Concat(SString &T, SString S1, Sstring S2)
{ 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]; return TRUE;
}
else if ( S1[0] < maxstrlen )
{ T[1..S1[0]] = S1[1..S1[0]];
T[S1[0]+1..maxstrlen] = S2[1..maxstrlen-S1[0]];
T[0] = maxstrlen; return FALSE;
}
else
{ T[0..maxstrlen] = S1[0..maxstrlen];
return FALSE;
}
}
4.2 串的表现和实现
以一组地址连续的存储单元存放串值字符序列,但它们的存
储空间是在程序执行过程中动态分配而得,所以也称为动态存储
分配的顺序表。在C语言中,利用和等动态存储管理函数,来根据
实际需要动态分配和释放字符数组空间。
typedef struct{
char *ch;
int length;
} HString;
4.2.2 堆分配存储表示
4.2 串的表现和实现
Status strassign(HString t, char *chars){
//生成一个其值等于串常量chars的串t
if(t.ch) free(t.ch);
for(i=0, c=chars; c; ++i, ++c) ; // 求chars的长度
if(!i) { t.ch=NULL; t.length=0; }
else
{ if(!(t.ch=(char *)malloc(i*sizeof(char))))
exit(overflow);
t.ch[0..i-1] = chars[0..i-1];
t.length=i;
}
}
4.2 串的表现和实现
3
Page 3
int strlen(HString s){ return s.length; }
Status clearstring(HString s)
{ if(s.ch) { free(s.ch); s.ch=NULL;}
s.length=0;
}
int strcmp(HString s, HString t)
{ for(i=0; i<s.length && i<t.length; ++i)
if(s.ch[i] != t.ch[i])
return(s.ch[i] - t.ch[i]);
return s.length-t.length;
}
4.2 串的表现和实现
Status concat(HString t, HString s1, HString s2)
{ if(t.ch) free(t.ch);
if(!(t.ch=(char*)malloc((s1.length+s2.length)*sizeof(char))))
exit(overflow);
t.ch[0..s1.length-1]=s1.ch[0..s1.length-1];
t.length=s1.length+s2.length;
t.ch[s1.length..t.length-1]=s2.ch[0..s2.length-1];
return OK;
}
4.2 串的表现和实现
Status substr(HString sub, HString s, int pos, int len)
{ if( pos<1 || pos>s.length || len<0 || len>s.length-pos+1 )
return ERROR;
if(sub.ch) free(sub.ch);
if(!len) { sub.ch=NULL; sub.length=0; }
else
{ sub.ch=(char *)malloc(len*sizeof(char));
sub.ch[0..len-1]=s[pos-1..pos+len-2];
s.length= len;
}
return OK;
}
4.2 串的表现和实现
顺序串上的插入和删除操作不方便,需要移动大量的字
符。因此,可用单链表方式来存储串值,串的这种链式存储
结构简称为链串。
一个链串由头指针唯一确定。这种结构便于进行插入和
删除运算,但存储空间利用率太低。
A B C D E F G H I # # # ^
head
head
A B C I ^
4.2.3 串的块链存储表示
4.2 串的表现和实现
4.3 串的模式匹配算法
……
S
i-j+1
S
i-j+2
……
S
i-1
S
i
S
i+1
……
P
1
P
2
……
P
j-1
P
j
……

失配位置
P
1
P
2
……
P
j-1
P
j
……
下次匹配位置
e.g: S=a b c a b c a b c d
P= a b c a b c d
a b c a b c d
模式右移一位
4.3.1 求子串位置的定位函数Index( )
模式匹配:求子串(模式)在主串的位置。
基本方法:从指定位置开始逐个比较主串与模式的字符,一旦
发现出现字符不匹配,则整个模式相对于原来的位
置右移一位。如下图所示:
最基本的模式匹配程序:
int Index( SString S, SString T, int pos )
// 在主串S的第POS个字符之后,寻找模式T的匹配位置
{ i = pos ; j = 1;
while ( i <= S[0] && j <= T[0] ) // 0 号单元存放串长
{ if ( S[i] == T[j] ) { ++i ; ++j ; }
else { i = i - j + 2; j = 1; }
}
if ( j > T[0] ) return i-T[0] // T 在S中的匹配起始位置
else return 0;
}
4.3 串的模式匹配算法
演示
4
Page 4
S=
aaaaaaaaab
P=
aab
a
、b
不等
模式右移一位
S=
aaaaaaaaab
P=
aab
a
、b
不等
模式右移一位
S=
aaaaaaaaab
P=
aab
a
、b
不等
模式右移一位
S=
aaaaaaaaab
P=
aab
a
、b
不等
模式右移一位
S=
aaaaaaaaab
P=
aab
S=
aaaaaaaaab
P=
aab
S=
aaaaaaaaab
P=
aab
S=
aaaaaaaaab
P=
aab
a
、b
不等
模式右移一位
a
、b
不等
模式右移一位
a
、b
不等
模式右移一位
完全匹配
n-m+1
匹配起始位置
4.3 串的模式匹配算法
4.3.2 Knuth-Morris-Pratt
模式匹配算法(KMP
算法)
说明基本模式匹配算法在最坏情况下时间复杂度为
O

n
*
m
)的实
例(n
为主串长度,m
为模式长度)。每比较m
次,移动模式一次。最后
在主串的
n-m+1
找到主串,比较
(n-m+1
)*
m


S =
abcabcabcd
P =
abcabcd
S =
abcabcabcd
P =
abcabcd
S =
abcabcabcd
P =
abcabcd
S =
abcabcabcd
P =
abcabcd
失配点
右移一位,仍失配又右移一位,仍失配
再右移一位,三次
比较之后,再进行
断点处的比较,比
较成功!
问题:
能否省去上述五次比
较,直接进行
S7

P4

间的比较呢?
本次比较省去? 本次比较省去?
三次比较省去?
4.3 串的模式匹配算法
说明
KMP
算法的实例:
i
j
S =
abcabcabcd
P =
abcabcd
S =
abcabcabcd
P =
abcabcd
失配点
直接寻找新匹配位置
i
j

S
i-j+1
S
i-j+2
……
S
i-1
S
i
S
i+1
……
P
1
P
2
……
P
j-1
P
j
……

失配点

分析:当
S
i

P
j
发生失配时,
S
i-j+1
S
i-j+2
……
S
i-1

P
1
P
2
……
P
j-1

S
i-k
S
i-k+1
……
S
i-1
S
i
S
i+1
……
P
1
……
P
k-1
P
k
……

失配点
如果:
P
1
P
2
………
P
k-1
= P
j-k+1
P
j-k+2
………
P
j-1

可以直接比较S
i

P
k
4.3 串的模式匹配算法
int
Index_KMP( SString S, SString T, int
pos )
// 在主串S的第POS个字符之后,寻找模式T的匹配位置
// 已知 NEXT 函数值,T 非空,1<=pos<=Strlength(S)
{ i = pos ; j = 1;
while
( i <= S[0] &&
j <= T[0] )
{ if
( j == 0 || S[i] == T[j] ) { ++i ; ++j ; }
else
j = next[ j ];
}
if
( j > T[0] ) return
i-T[0] // T在S中的匹配起始位置
else return
0;
} // Index_KMP
分享到:
评论

相关推荐

    尚硅谷-尚医通 笔记代码资料.zip

    它支持多种数据结构如字符串、哈希、列表、集合和有序集合,适用于多种应用场景,例如会话存储、计数器、排行榜等。在尚医通项目中,Redis可能被用来缓存频繁访问的用户信息、订单状态或其他关键数据,以提高系统的...

    数据结构 课件 笔记【完美版】【初学者福音】

    本资源包含“数据结构”的课件和笔记,非常适合初学者作为学习资料,以下是根据这些主题展开的一些关键知识点: 1. **数组(Array)**:数组是最基础的数据结构,它在内存中分配连续的空间来存储相同类型的数据元素...

    MongoDB学习笔记

    MongoDB 是一种流行的开源、高性能、无模式的文档...它的易用性、丰富的功能和优秀的性能使其成为许多开发者的首选数据库系统。通过学习和实践,开发者可以充分利用MongoDB的优势,构建高效的数据存储和处理解决方案。

    c语言教程及读书笔记

    通过C语言老师制作的课件和读书笔记,你不仅能够掌握基础概念,还能深入了解实际编程中的技巧和最佳实践。在实践中不断应用和巩固所学,你将很快步入编程者的殿堂,用C语言创造出自己的精彩程序。

    Android学习入门笔记.zip

    Android学习入门笔记主要涵盖了一系列关于Android开发的基础知识,旨在帮助初学者快速掌握这一全球最流行的移动操作系统...通过阅读“Android学习入门笔记”中的学习课件,你应该能逐步建立起对Android开发的全面认知。

    C语言--程序设计导论课件

    课件可能包含PPT、笔记、习题解答等多种形式,帮助学生全面理解C语言的各个知识点,为后续的编程学习打下坚实基础。在实际的学习过程中,不断实践和调试代码是非常重要的,因为编程是一项实践性极强的技能。同时,...

    学习邓俊辉的数据结构书籍和浙大的数据结构的视频课程总结.zip

    在ljg_resource1这个文件中,可能包含了邓俊辉教授书籍的笔记、课件、习题解答或者浙江大学视频课程的讲义等资源。这些资料可以帮助学习者巩固理论知识,加深理解,并提供实践练习的机会。 总的来说,邓俊辉的数据...

    MIT6.00.1x-Introduction-to-Computer-Science-and-Programming-Using-Python:我的作业笔记

    在“MIT6.00.1x-Introduction-to-Computer-Science-and-Programming-Using-Python-master”这个压缩包中,包含了课程的全部资料,可能包括课件、练习题、示例代码和作业解决方案。这些资源有助于学生自主学习,通过...

    2018传智python 15期 视频教程 今年刚完结

    9. **课件辅助**:配合视频教程的课件,包含了讲义、笔记和练习题,为自主学习提供了便利,让学习更加高效。 总之,这个2018传智Python 15期的教程是一套全面的Python学习资源,无论你是编程新手还是希望提升技能的...

    6语文园地七——小学生ppt学习课件

    - 资料、课件、范文、试卷、教案下载。 - **使用限制**: - 可用于个人/公司的商业演示。 - 不可用于任何形式的在线付费下载。 - 不允许收集整理免费资源后制作成光盘销售。 以上内容详细介绍了PPT模板和文档在...

    中国石油大学(北京)《Java语言程序设计》期末考试试卷(含答案).pdf

    由于提供的文件内容中出现了大量重复的字眼“创创大帝”,这显然不是一份正常的技术或学术文档的内容。...在准备期末考试或进行学习时,建议学生参考正规的教材、教案和课堂笔记来掌握正确的学习内容。

Global site tag (gtag.js) - Google Analytics