串的定义及基本运算
合集下载
数据结构第5章 串和广义表

5.1 串的定义和基本运算
• (4)串的连接StrCat(S,T)。 • 初始条件:串S和T存在。 • 操作结果:将串T的值连接在串S的后面。 • (5)求子串SubString(Sub,S,pos,len)。 • 初始条件:串S存在,1≤pos≤StrLength(S)且
1≤len≤StrLength(S)-pos+1。 • 操作结果:用Sub返回串S的第pos个字符起长度为len的
1≤len≤StrLength(S)-pos+1。 • 操作结果:从串S中删除第pos个字符起长度为len的子串。 • (9)串的替换StrReplace(S,T,V)。 • 初始条件:串S,T和V存在,且T是非空串。 • 操作结果:用V替换串S中出现的所有与T相等的不重叠子
串。 • (10)判断串空StrEmpty(S)。 • 初始条件:串S存在。 • 操作结果:若串S为空串,则返回1;否则返回0。
• (1)非紧凑存储。设串S="Hello boy",计算机字长为32 位(4个Byte),用非紧凑格式一个地址只能存一个字符, 如图5-2所示。其优点是运算处理简单,但缺点是存储空 间十分浪费。
• (2)紧凑存储。同样存储S="Hello boy",用紧凑格式一 个地址能存四个字符,如图5-3所示。紧凑存储的优点是 空间利用率高,缺点是对串中字符处理的效率低。
•}
5.3 串的基本运算的实现
• (3)求子串操作。求串S从第pos位置开始,长度为len的 子串,并将其存入到串Sub中。操作成功返回1,不成功 返回0。其算法描述如下:
• int SubString(String *S,String *Sub,int pos,int len)
串的定义及其基本运算

一个长度为零的串称为空串,表示为s =ˊˊ。
空格也是合法字符,它可以出现在较长的字符 串中,也可以单独出现 。例如A=ˊabc def ˊ就是 长度为7的字符串,因为abc和def中间有一个空 格字符。
串
串的基本运算
1. 求串的长度len(s); 2. 判断两个串是否相等equal(s,t); 3. 两个串的连接concat(s,t); 4. 求某串的子串sub(s,start,ln,t); 5. 插入子串insert(s1,i,s2); 6. 删除子串delete(s,i,j); 7. 置换replace(s,t,r)。
返回
串
数据结构
数据结构
1.1 串的定义
串(string)是由有限个字符组成的序列,又称为 字符串(character string),一般记为:
s=ˊa1 a2 a3…anˊ 其中s是串名,用单引号括起来的字符序列是串 的符值;。 n为ai串(1<中=字i<=符n)的可个以数是,字称母为、串数的字长或度其。他字
空格也是合法字符,它可以出现在较长的字符 串中,也可以单独出现 。例如A=ˊabc def ˊ就是 长度为7的字符串,因为abc和def中间有一个空 格字符。
串
串的基本运算
1. 求串的长度len(s); 2. 判断两个串是否相等equal(s,t); 3. 两个串的连接concat(s,t); 4. 求某串的子串sub(s,start,ln,t); 5. 插入子串insert(s1,i,s2); 6. 删除子串delete(s,i,j); 7. 置换replace(s,t,r)。
返回
串
数据结构
数据结构
1.1 串的定义
串(string)是由有限个字符组成的序列,又称为 字符串(character string),一般记为:
s=ˊa1 a2 a3…anˊ 其中s是串名,用单引号括起来的字符序列是串 的符值;。 n为ai串(1<中=字i<=符n)的可个以数是,字称母为、串数的字长或度其。他字
串的定义和基本运算(精)

s1->str=(char*)malloc(sizoef(char));s1->str[0]=’\0’;s1>length=0;return ERROR;} s1->str=(char*)malloc((len+1)*sizeof(char)); if (!s1.str) return ERROR; s1->str[0..len-1]=s2.str[start-1..start+len -2]; s1->str[len]=’\0’; s1->length=len; return OK; }
int length;
}STRING; 不同的定义形式,算法中的处理也略有不同。下 面我们将给出在第二种顺序存储方式下串的几个基本 操作的算法。
(1) 串的赋值 int StringAssign(STRING*s,char *string_constant) { if (s->str) free(s->str);
2. 链式存储结构
由于串结构中每个数据元素为一个字符,所以最 直接的链式存储结构是每个结点的数据域存放一个字 符。举例:
S
s
t r i n g^
图 4-1
优点是操作方便;不足ቤተ መጻሕፍቲ ባይዱ处是存储密度较低。所 谓存储密度为:
串值所占的存储单元 存储密度
实际分配的存储密度
若要将多个字符存放在一个结点中,就可以缓解 这个问题。举例:
(4)串连接 int Concat(STRING *s1,STRING s2) { STRING s; StringAssign(&s,s1->str); //将s1原来的内容保留在s中 len=Length(s1)+Length(s2);
int length;
}STRING; 不同的定义形式,算法中的处理也略有不同。下 面我们将给出在第二种顺序存储方式下串的几个基本 操作的算法。
(1) 串的赋值 int StringAssign(STRING*s,char *string_constant) { if (s->str) free(s->str);
2. 链式存储结构
由于串结构中每个数据元素为一个字符,所以最 直接的链式存储结构是每个结点的数据域存放一个字 符。举例:
S
s
t r i n g^
图 4-1
优点是操作方便;不足ቤተ መጻሕፍቲ ባይዱ处是存储密度较低。所 谓存储密度为:
串值所占的存储单元 存储密度
实际分配的存储密度
若要将多个字符存放在一个结点中,就可以缓解 这个问题。举例:
(4)串连接 int Concat(STRING *s1,STRING s2) { STRING s; StringAssign(&s,s1->str); //将s1原来的内容保留在s中 len=Length(s1)+Length(s2);
数据结构第4章 串

ring s, SString t)
/*若串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;
/*若串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;
第5章-串

7. 串删除 StrDel (s,i,len) 操作条件:串s存在 操作成果:删除串s 中第i个字符起长度为len旳
子串,s旳串值变化。
5-2 串旳表达和实现
一.串旳顺序存储
1.存储方式:同一般旳线性表旳顺序存储构 造完全相同.用一组地址连续旳存储单元存 储字符序列, 据预定义大小,为每个定义旳串 变量分配一种固定长度旳存储区。
2.索引存储旳例子 设字符串:A=”Red” B=”Yellow” C=”Blue” D=”White” 用指针free指向堆中未使用空间旳首地址。
索引表: Name A B C D ……
Length 3 6 4 5 ……
Stradr 0 3 9
……
free 堆:
R e d Y e l l o w B l u E Wh i t e …
为 len 旳子串。而且赋予给s2,len=0得到旳是空串。 【例5-7】 SubStr ("abcdefghi",3,4) = "cdef”
4. 串比较: Strcmp (s1,s2) 操作条件:串s1,s2存在。 操作成果:若s1= =s2,返回值为0;若s1<s2, 返
回值<0;若s1>s2, 返回值>0。
(2)使用gets() 函数
格式为:gets(字符数组名); 【例5-3】 char str[10]; printf("Input your str: "); gets(str);
•使用gets ()方式输入时,字符串中允许具有空
格。
2.字符串旳输出
字符串旳输出也有两种措施:
(1)使用printf () 函数 使用printf () 函数时,输出格式中要设置"%s",再
止符,以此表达串旳结尾。例如C语言中处理定长串旳措施
子串,s旳串值变化。
5-2 串旳表达和实现
一.串旳顺序存储
1.存储方式:同一般旳线性表旳顺序存储构 造完全相同.用一组地址连续旳存储单元存 储字符序列, 据预定义大小,为每个定义旳串 变量分配一种固定长度旳存储区。
2.索引存储旳例子 设字符串:A=”Red” B=”Yellow” C=”Blue” D=”White” 用指针free指向堆中未使用空间旳首地址。
索引表: Name A B C D ……
Length 3 6 4 5 ……
Stradr 0 3 9
……
free 堆:
R e d Y e l l o w B l u E Wh i t e …
为 len 旳子串。而且赋予给s2,len=0得到旳是空串。 【例5-7】 SubStr ("abcdefghi",3,4) = "cdef”
4. 串比较: Strcmp (s1,s2) 操作条件:串s1,s2存在。 操作成果:若s1= =s2,返回值为0;若s1<s2, 返
回值<0;若s1>s2, 返回值>0。
(2)使用gets() 函数
格式为:gets(字符数组名); 【例5-3】 char str[10]; printf("Input your str: "); gets(str);
•使用gets ()方式输入时,字符串中允许具有空
格。
2.字符串旳输出
字符串旳输出也有两种措施:
(1)使用printf () 函数 使用printf () 函数时,输出格式中要设置"%s",再
止符,以此表达串旳结尾。例如C语言中处理定长串旳措施
第5章 串

【例5-8】子串定位 例 IndexStr ("abcdebda","bc")=2 " "" " IndexStr ("abcdebda","ba")= 0 " "" " 6. 串插入 InsStr (s,t,i) 操作条件: , 存在 操作条件:串s,t存在 操作结果:将串 插入到串 的第i个字符前 的串值发 插入到串s 个字符前, 操作结果:将串t插入到串 的第 个字符前,s的串值发 生改变. 生改变. 7. 串删除 DelStr(s,i,len) 操作条件: 存在 操作条件:串s存在 操作结果:删除串 中第i个字符起长度为 的子串, 个字符起长度为len的子串 操作结果:删除串s 中第 个字符起长度为 的子串,s 的串值改变. 的串值改变.
5-1-2 串的输入与输出 1.字符串的输入 . 语言中, 在C语言中,字符串的输入有两种方法: 语言中 字符串的输入有两种方法: (1)使用 )使用scanf () 函数 使用scanf () 函数时,输入格式中要设置"%s", 函数时,输入格式中要设置" ", 使用 再加上字符数组名称. 再加上字符数组名称. 【例5 - 2 】 char str[10]; printf(" printf("Input your str: "); scanf("%s" scanf("%s",str); 使用 使用scanf ()方式输入时,字符串中不能含有空格. 方式输入时, 方式输入时 字符串中不能含有空格. 在C++中还可以用输入流对象cin . C++中还可以用输入流对象 中还可以用输入流对象cin
第五章 字符串

(5)StrIndex(a,b) 功能:求子串b在主串a中第1次出现的第1 功能:求子串b在主串a中第1次出现的第1个字 符在a中的序号,若b不是a 符在a中的序号,若b不是a的子串,则返回 -1。 例如: b=“+”,求StrIndex(a,b)。 例如:a=“a+b+c”, b=“+”,求StrIndex(a,b)。 结果: 结果 StrIndex(a,b)=2 (6)StrEqual(a,b) 功能:判断串a和串b是否相等,相等返回1 功能:判断串a和串b是否相等,相等返回1, 否则返回0 否则返回0。 例如: b=“chald”,求StrEqual(a,b)。 例如:a=“child”, b=“chald”,求StrEqual(a,b)。 结果:返回0 结果:返回0。
(2)求子串的运算及其算法 (2)求 //用sub返回串s中从第m个字符开始至第n个字符为止的 //用sub返回串s中从第m个字符开始至第n 子串。1<=m<=n<=s.len子串。1<=m<=n<=s.len-1 int SubStr_h(hstring s,int m,int n,hstring &sub) { int k,j; if(sub.ch) delete sub.ch;//释放sub原有的空间 sub.ch;//释放sub原有的空间 if(m<0||n>s.lenif(m<0||n>s.len-1||m>n) return 0;//参数错误 0;//参数错误 else// { k=n-m+1; sub.ch=new char[k]; j=0;//分配sub空间 k=nj=0;//分配sub空间 for(k=m;k<=n;k++)//将子串拷贝到sub串中 for(k=m;k<=n;k++)//将子串拷贝到sub串中 {sub.ch[j]=s.ch[k]; j++;} } sub.len=nsub.len=n-m+1;return 1;//保存sub串的长度 1;//保存sub串的长度 }
数据结构 第2章 串

if(j==m) return(i);
} return(-1);
算法评价: 比较总次数:m*(n-m+1) 时间复杂度:O(m*(n-m))
}
若n>>m:O(m*n)
2)匹配算法——KMP算法
t= aaabcaaadcaaadaaaabc p= aaada
算法:如果存在一个整数k(k<j),使得模式P中 开头k个字符与前面k个字符相同,则只要从 模式P中的p[k]开始与正文T中的t[i]开始比较, 就可以省去前面的k次比较。
01 2 3 4 5
m x不在p中,或只在末尾 1)求d(x)
m-i-1 否则
2)不匹配,向右移d(x)(对应后,从最后一个字符比较) 匹配,取i-m+1
0 1 2 3 4 5 6 7 8 9 10 12 14 16 18 20 22
2) 非紧缩格式是以一个存储单元为单位, 也就是一个存储单元
中仅放一个字符。 在一个程序中使用的串变量较少, 且各串变 量的长度又都较短时,如果希望该程序处理字符的速度尽可能 快, 那么选择非紧缩格式比较合适。 在这种存储格式中, 串的长 度是隐式的, 串所占用存储单元的个数即为串长。
例: 假设一存储单元可以存放4个字符, 同样 对于字串(This is a flag), 共需14个存储单元, 其存放的直观表示如表 4.2。 这种存储格式 对存储空间的利用率仅为25%, 但如上所述, 该方法在字符加工处理方面会节省时间。
2、算法: 回溯法(朴素的模式匹配法) KMP算法 BM算法
1) 回溯法 成功匹配:返回首次出现的起始位置
失败匹配:返回-1
匹配算法——简单算法
t=“abcdabcdabccdacd”
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、串和基本概念 串(String)是零个或多个字符组成的有限序列。 一般记作:S=“a1a2a3…an” 其中S是串名,双引号括起来的字符序列是串值; ai(1≦i≦n)可以是字母、数字或其它字符;串中所包 含的字符个数称为该串的长度。长度为零的串称为空 串(Empty String),它不包含任何字符。 2018年11月26
日 8
第四章 串
4.2 串的存储结构
4.2.1 串的定长顺序存储 类似于顺序表,用一组地址连续的存储单元存储串值 中的字符序列,所谓定长是指按预定义的大小,为每 一个串变量分配一个固定长度的存储区,如:
1. 类似顺序表,用一个指针来指向最后一个字 符,这样表示的串描述如下: typedef struct { char data[MAXSIZE]; int curlen; } SeqString;
2018年11月26 日
9
第四章 串
s.data
0 S
1 t
2 u
3 d
4 e
5 n
s.curlen … MAXSIZE-1
2.在串尾存储一个不会在串中出现的特殊字符作为串的 终结符,以此表示串的结尾。比如C语言中处理定长串 的方法就是这样的,它是用'\0'来表示串的结束。 3. 设定长串存储空间:char s[MAXSIZE+1]; 用s[0] 存放串的实际长度,串值存放在s[1]~s[MAXSIZE],字 符的序号和存储位置一致,应用更为方便。的串称为空白串 (Blank String) 。
注意:空串和空白串的不同。 二、串的术语 1.主串和子串:串中任意个连续字符组成的子序列称 为该串的子串,包含子串的串相应地称为主串。通常 将子串在主串中首次出现时的该子串的首字符对应的 主串中的序号,定义为子串在主串中的序号(或位 置)。例如,设A和B分别为 A=“This is a string” B=“is” 则B是A的子串,A为主串。
4.求子串SubStr (s,i,len): 操作条件:串s存在,1≤i≤StrLength(s), 0≤len≤StrLength(s)-i+1。 操作结果:返回从串s的第i个字符开始的长度为 len 的子串。len=0得到的是空串。
2018年11月26 日
6
第四章 串
5.串比较 StrCmp(s1,s2) 操作条件:串s1,s2存在。操作结果:若s1= =s2,操 作返回值为0;若s1<s2, 返回值<0;若s1>s2, 返回 值>0。
8.串删除 StrDelete(s,i,len) 操作条件:串s存在,1≤i≤StrLength(s), 0≤len≤StrLength(s)-i+1。 操作结果:删除串s 中从第i个字符开始的长度为 len的子串,s的串值改变。
9.串替换 StrRep(s,t,r) 操作条件:串s,t,r存在,t不为空。 操作结果:用串r 替换串s中出现的所有与串t相等 的不重叠的子串,s的串值改变。 2018年11月26
2018年11月26 日
5
第四章 串
3.连接操作 :StrConcat (s1,s2,s) 或StrConcat (s1,s2)
操作条件:串s1,s2存在。
操作结果:两个串的联接就是将一个串的串值紧接 着放在另一个串的后面,连接成一个串。前者是产生 新串s,s1和s2不改变; 后者是在 s1的后面联接 s2的串 值,s1改变, s2不改变。
6.子串定位 StrIndex(s,t):找子串t在主串s中首 次出现的位置 操作条件:串 s,t存在。操作结果:若t∈s,则操作 返回t在s中首次出现的位置,否则返回值为-1。
2018年11月26 日
7
第四章 串
7.插入 StrInsert(s,i,t) 操作条件:串s,t存在,1≤i≤StrLength(s)+1。 操作结果:将串t插入到串s 的第i个字符位置上。
第四章 串
4.1 串的定义及基本运算
4.2 串的存储结构
4.3 模式匹配算法的实现 4.4 小结与习题
2018年11月26 日
1
第四章 串
串(字符串)是一种特殊的线性表,它的数据元 素仅由一个字符组成,计算机非数值处理的对象经常 是字符串数据,在事物处理程序中,一般也是作为字 符串处理的。 4.1 串的定义及基本运算
2018年11月26 日
10
第四章 串
4.2.2
定长顺序串的基本运算
1.串联接:把两个串s1和s2首尾连接成一个新串s 。 int StrConcat1(s1,s2,s) { int i=0 , j, len1, len2; len1= StrLength(s1); len2= StrLength(s2) if (len1+ len2>MAXSIZE-1) return 0 ; j=0; while(s1[j]!=’\0’) { s[i]=s1[j];i++; j++; } j=0; while(s2[j]!=’\0’) { s[i]=s2[j];i++; j++; } s[i]=’\0’; return 1; }
2018年11月26 日
3
第四章 串
2.子串的位置:子串的第一个字符在主串中的序号称 为子串的位置。 B在A中出现了两次,首次出现所对 应的主串位置是3。因此,称B在A中的序号(或位置) 为3。 特别地,空串是任意串的子串,任意串是其自身的 子串。 3.串相等:称两个串是相等的,是指两个串的长度 相等且对应字符都相等。
2018年11月26 日
4
第四章 串
三、串的基本运算 1.求串长StrLength(s): 操作条件:串s存在;操作结果:求出串s的长度。 2.串赋值StrAssign(s1,s2) 操作条件: s1是一个串变量,s2或者是一个串常量, 或者是一个串变量(通常s2 是一个串常量时称为串赋 值,是一个串变量称为串拷贝)。 操作结果:将s2的串值赋值给s1, s1原来的值被覆 盖掉。
2018年11月26 日
11
第四章 串
2. 求子串 int StrSub (char *t, char *s, int i, int len) { int slen; slen=StrLength(s); if ( i<1 || i>slen || len<0 || len>slen-i+1) { printf("参数不对"); return 0; } for (j=0; j<len; j++) t[j]=s[i+j-1]; t[j]=’\0’; d e n t.data 例2. s.curlen return 1;}