第3章 串
【例3-1】已知字符串:a=“an apple”,b=“other hero”,c=“her”,求:
(1)concat(substr(a,1,2),b)。
(2)replace(a,substr(a,5,1),c)。
(3)index(a,c)和index(b,c)。
解:
(1)返回值为“another hero”,其中substr(a,1,2)的返回值为“an”。
(2)返回值为“an aherherle”,其中substr(a,5,1)的返回值为“p”。
(3)返回值分别为0和3。
//串的第一个元素就是下标为1的元素
连接// cat顺序连接子串
取代//replace(s,i,t)用串t取代s中i
求子串// substr(s,i,len) 取出s串中位置为i长度为len的串
查找//index(s,t) 返回s串中t首次出现的位置,没有返回0(这道题子串是her)
other
删除//delstr(s,t,len) 删除串s中第i个字符起长度为len的子串
插入//insstr(s,t,i)将串t插入串s中的第i个字符前
3.串的顺序存储结构(顺序串)
串的顺序存储方式类似于线性表的顺序存储方式,其存储结构用C语言描述为:
typedef struct strnode {
char data[maxlen];
int len;
}SeqString; //定义顺序串类型
【例3-2】设定串采用顺序存储结构,写出对串s1和串s2比较大小的算法。串值大小按字典排序(升序)方式,返回值等于-1,0和1分别表示s1<s2,s1=s2和s1>s2。
解: 算法思想:
(1)比较s1和s2共同长度范围内的对应字符:
若s1的字符>s2的字符,返回;
若s1的字符<s2的字符,返回;
若s1的字符=s2的字符,按上述规则继续比较;
(2)当(1)中对应字符均相同时,比较和的长度:
两者相等时,返回0;
前者>后者时,返回1;
前者<后者时,返回-1;
算法描述如下:
#define MAXLEN 256
struct strnode{
char data[MAXLEN];
int len;
}SeqString; //定义顺序串类型
int strcmp(SeqString s1, SeqString s2)//比较串s1和串s2的大小
{ int comlen;
if (s1.len<s2.len) comlen=s1.len; //求出串s1和串s2的共同长度
else comlen=s2.len;
for(i=0;i<comlen;i++) //在共同长度内逐个字符比较
if(s1.ch[i]<s2.ch[i]) return (-1); //s1<s2
else
if(s1.ch[i]>s2.ch[i]) return (1); //s1>s2
if(s1.ch[i]= =s2.ch[i]) return (0); //s1=s2
else
if(s1.ch[i]<s2.ch[i]) return (-1); //s1<s2
else return (1); //s1>s2
}
习题3
一、单项选择题
1. 空串与空格字符组成的串的区别在于(1.B )。
A.没有区别 B.两串的长度不相等
C.两串的长度相等 D.两串包含的字符不相同
2. 一个子串在包含它的主串中的位置是指( 2.D)。
A.子串的最后那个字符在主串中的位置
B.子串的最后那个字符在主串中首次出现的位置
C.子串的第一个字符在主串中的位置
D.子串的第一个字符在主串中首次出现的位置
3. 下面的说法中,只有( 3.C )是正确的。
A.字符串的长度是指串中包含的字母的个数
B.字符串的长度是指串中包含的不同字符的个数
C.若T包含在S中,则T一定是S的一个子串
D.一个字符串不能说是其自身的一个子串
4. 两个字符串相等的条件是(4.D )。
A.两串的长度相等
B.两串包含的字符相同
C.两串的长度相等,并且两串包含的字符相同
D.两串的长度相等,并且对应位置上的字符相同
5. 若SUBSTR(S,i,k)表示求S中从第i个字符开始的连续k个字符组成的子串的操作,则对于S=“Beijing&Nanjing”,SUBSTR(S,4,5)=( 5.B )。
A. “ijing” B. “jing&”
C. “ingNa” D. “ing&N”
//字符串中&就是表示字符串
6. 若INDEX(S,T)表示求T在S中的位置的操作,则对于S=“Beijing&Nanjing”,T=“jing”,INDEX(S,T)=(6.C)。
A.2 B.3 C.4 D.5
7. 若REPLACE(S,S1,S2)表示用字符串S2替换字符串S中的子串S1的操作,则对于S=“Beijing&Nanjing”,S1=“Beijing”,S2=“Shanghai”,REPLACE(S,S1,S2)=( 7.D )。
A. “Nanjing&Shanghai” B. “Nanjing&Nanjing”
C. “ShanghaiNanjing” D. “Shanghai&Nanjing”
8. 在长度为n的字符串S的第i个位置插入另外一个字符串,i的合法值应该是( 8.C )。
A.i>0 B. i≤n
C.1≤i≤n D.1≤i≤n+1
9. 字符串采用结点大小为1的链表作为其存储结构,是指(9.D )。
A.链表的长度为1
B.链表中只存放1个字符
C.链表的每个链结点的数据域中不仅只存放了一个字符
D.链表的每个链结点的数据域中只存放了一个字符1
二、填空题
1. 计算机软件系统中,有两种处理字符串长度的方法:一种是____固定长度_______,第二种是______________设置长度指针_____。
2. 两个字符串相等的充要条件是________两个串的长度相等_____________和___________对应位置的字符相等________。
3. 设字符串S1= “ABCDEF”,S2= “PQRS”,则运算S=CONCAT(SUB(S1,2,LEN(S2)),SUB(S1,LEN(S2),2))后的串值为_________ BCDEDE __________。
4. 串是指___________含n个字符的有限序列 (n≥0)________。
5. 空串是指________不含任何字符的串___________,空格串是指______仅含空格字符的字符串_____________。
三、算法设计题
1. 设有一个长度为s的字符串,其字符顺序存放在一个一维数组的第1至第s个单元中(每个单元存放一个字符)。现要求从此串的第m个字符以后删除长度为t的子串,m<s,t<(s-m),并将删除后的结果复制在该数组的第s单元以后的单元中,试设计此删除算法。
1.算法描述为:
int delete(r,s,t,m) //从串的第m个字符以后删除长度为t的子串
char r[ ];
int s,t,m;
{ int i,j;
for(i=1;i<=m;i++)
r[s+i]=r[i];
for(j=m+t-i;j<=s;j++)
r[s-t+j]=r[j];
return (1);
} //delete
2. 设s和t是表示成单链表的两个串,试编写一个找出s中第1个不在t中出现的字符(假定每个结点只存放1个字符)的算法。
2.算法思想为:
(1)链表s中取出一个字符;将该字符与单链表t中的字符依次比较;
(2)当t中有与从s中取出的这个字符相等的字符,则从t中取下一个字符重复以上比较;
(3)当t中没有与从s中取出的这个字符相等的字符,则算法结束。
设单链表类型为LinkList;注意,此时类型 LinkList中的data成分为字符类型。
LinkString find(s,t)
LinkString *s, *t;
{ LinkString *ps, *pt;
ps=s;
while(ps!=NULL)
{ pt=t;
while((pt!=NULL)&&(ps->data!=pt->data))
pt=pt->next;
if(pt= =NULL)
ps=NULL;
else
{ ps=ps->next;
s=ps;
}
}
return s;
} //find