第四章 串答案
-
第四章
答案
4.1
简述下列每对术语的区别:
空串和空白串;
串常量和串变量;<
/p>
主串和子串;
静态分配的顺序串和动态分配的顺序串;
目标串和模式串;有效位移和无效位移。
答:<
/p>
●
空串是指不包含任何字符的串,它的长度为零。
空白串是指包含一个或多个空格的串,空格也是字符。
●
串常量是指在程序中只可引用但不
可改变其值的串。
串变量是可以在运行中改变其值的。
●
主串和子串是相对的,一个串中任意个连续字符组成的串就是
这个串的子串,而包含子
串的串就称为主串。
●
静态分配的顺序串是指串的存储空
间是确定的,即串值空间的大小是静态的,在编译时
刻就被确定。
动态分配的顺序串是在编译时
不分配串值空间,在运行过程中用
malloc
和
free
等函数
根据需要动态地分配和释放字符数组
的空间
(
这个空间长度由分配时确定,也是顺序存储空
间
)
。
●
目标串和模式串
< br>:
在串匹配运算过程中,
将主串称为目标串,
而将需要匹配的子串称为模
式串,两者是相对的。
●
有效位移和无效位移:在串定位运
算中,模式串从目标的首位开始向右位移,每一次合
法位移后如果模式串与目标中相应的
字符相同,则这次位移就是有效位移
(
也就是从此位置
开始的匹配成功
)
,反之,若有不相同的字符存
在,则此次位移就是无效位移
(
也就是从此位
< br>置开始的匹配失败
)
。
4.2
假设有如下的串说明:
char
s1[30]=
(1)
在执行如下的
每个语句后
p
的值是什么
?
p=stchr(s1,'t'); p=strchr(s2,'9');
p=strchr(s2,'6');
(2)
在执行下列语句后,
s3
的值是什么
?
strcpy(s3,s1); strcat(s3,
p>
(3)
调用函数
strcmp(s1,s2
)
的返回值是什么
?
(4)
调用函数
strcmp(&s1[5],
p>
的返回值是什么
?
(5)
调用函数
stlen(strcat(s1,s2)
)
的返回值是什么
?
解:
(1) stchr(*s,c)
函数的功能是查找字符
c
在串
s
中的位置,若找到,则返回该位置,否则
返回
NULL
。
因此
:
执行
p=stchr(s1,'t');
后
p
的值是指向第一个字符
t
的位置
,
也就是
p
==&s1[1]
。
执行
p=strchr(s2,'9
');
后
p
的值是指向
s2
串中第一个
9
所在的位置
,
也就是
p==&s2[9]
。
`
执行
p=strchr(s2,'6');
之后,
p
的返回值是
NULL
。
(2)strcpy<
/p>
函数功能是串拷贝,
strcat
函数的
功能是串联接。所以
:
在执行
strcpy(s3,s1);
后,
s3
的值是
在执行
strcat(s3,
后,
s3
的值变成
在执行完
strcat(s3,s2);
后,
s3
< br>的值就成了
(3)
函数
strcmp(
串
1
,串
2)
的功能是串比较,按串的大小
进行比较,返回大于
0
,等于
0
或小于
0
的值以表示串
1
比串
2
大,串
< br>1
等于串
2
,串
1
小于串
2
。因此在调用函
数
strcmp(s1,s2)
后,返回值是大于
0
的数
(
字符比较是以
p>
ascii
码值相比的
)
(4)
首先,我们要知道
&s1[5]
是一个地址,当放在函数
strcm
p
中时,它就表示指向以它为
首地址的一个字符串,所以在
p>
strcmp(
&s1[5],
中,前一
个字符串值是
用它和
< br>比较,应该是后者更大,所以返回值是小于
0
的数。
p>
(5)strlen
< br>是求串长的函数,我们先将
s1,s2
联接起来,值是<
/p>
5,1999
数
一数有几个字符
?
是不是
23
个
(
空格也是一个
)?
所以返回值是
23
。
< br>
4.3
设
T[0..n-1
]=
当用模式串匹配目标
串
T
时,请给出所有的有效位移。算法
NaiveStrMatch(T,P
)
返回的位移是哪一
个位移。
解:所有的有效位移
i
的值为:
2
,
5
,
< br>9
。
算法
NaveStrMatch(T
,P)
的返回值是第一个有效位移,因此是
2
< br>。
4.4
利用
C
的库函数
strlen,strcpy
和
strcat
写一算法
void
StrInsert(char
*S,
char *T, int i),
将串
T
插入到串
S
的第
< br>i
个位置上。若
i
大于
S
的长度,则
插入不执行。
解:算法如下:
void StrInsert(char *S, char *T, int i)
{//
将
串
T
插入到串
S
的第
i
个位置上
char *Temp;
if(i<=strlen(S))
{
Temp=(char
*)malloc(sizeof(char[Maxsize]));//
设置一个临时串
p>
strcpy(Temp,&S[i]);//
将第
i
位起以后的字符拷贝到临时串中
strcpy(&S[i], T);//
< br>将串
T
拷贝到串
S
的第
i
个位置处,覆盖后面的字符
< br>
strcat(S,Temp);
//
把临时串中的字符联接到串
S
后面
free( Temp );
}
}
4.5
利
用
C
的
库
函
数<
/p>
strlen
和
strcpy(
或
strncpy)
写
一
算
法
void
StrDelete(char *S,int i, int m)
< br>删去串
S
中从位置
i
开始的连续
m
个字符。
若
i≥strlen(S),则没有字符被删除;若
i+m≥st
rlen(S),则将
S
中从位置
i<
/p>
开
始直至末尾的字符均删去。
解:算法如下:
void StrDelete(char *S, int i ,int m)
{
//
串删除
char
Temp[Maxsize];//
定义一个临时串
pos 个字符复制到 <
br>加密算法可以用两个串中字符的一一对应关系来实现, <
br>P
面设计的一系列算法。算法如下:
if(i+m
{
strcpy (Temp, &S[i+m]);//
p>
把删除的字符以后的字符保存到临时串中
strcpy( &S[i],Temp);//
用临时串中的
字符覆盖位置
i
之后的字符
}
else if(i+m>=strlen(S)&& i
{
strcpy(&S[i],
p>
把位置
i
的元素置为
'0'
,表示串结束
}
}
4.6
以
HString
为存储表示,写一个
求子串的算法。
解:
HString
是指以动态分配顺序串为存储表示,其定义为:
typedef struct {
char *ch;
int length;
}HString;
void *substr( HString *sub,HString
*s,int pos,int len)
{//
用
s
ub
返回串
s
的第
个字符起长度为
len
的子
串。
sub
初始时为一空串
p>
//pos
的合法位置为
0<=pos<=
s->length-1
int i;
if
(pos<0||pos>s->length-1||len<=0)
Error(
参数不合法,子串为空串
if (s->length
串中没
有足够的元素
sub->len=s->length-
pos;//
设置子串的串长
else sub->length=len;
//
设置子串的串长
sub->ch=(char *)malloc(len*sizeof(char)
);//
为
sub->ch
申请结点空
间
for(i=0;i
将
s
串中
p
os
位置开始的共
sub->length
sub
串中
sub->ch[i]=s->ch[pos+i];
}
4.7
一个文本串可用事先给定的字母映射表进行加密。例如
,设字母映射表为:
a b c d e f g h i j k l m n o p q r s t
u v w x y z
n g z q t c o b m u h e l k p d a w x f
y i v r s j
p>
则字符串
被加密为
试写一算法将输入的文本串进行
加密后输出;另写一算法,将输
入的已加密的文本串进行解密后输出。
解:
当输入一个字符时,
由算法在串
Original
中查找其位置,
然后用串
Cipher
中相应位置的字
符去替换原来的字符就可以了。
解
密算法则恰恰相返。
设字母映射表的存储结构如下:
#define MaxStrSize 26
typedef struct{
char Original[MaxStrSize];
//
可容纳
26
个字符,并依次存储在
Original[0..n]
中
char Cipher[MaxStrSize]; //
可
容纳
26
个字符,并依次对应
Orig
inal
表中的密码
int length;
}SeqString;
void Encrypt( SeqString
codetable)
{//
加密算法。
char ch;
int i;
while((ch=getchar())!='0')
{
i=0;
while
(i<&&ch!=al[i])
i++;
if (i>=)
Error(
else
printf(
}
printf(
}
void Decipher(SeqString Original ,
SeqString Cipher, char* T)
{//
解密算法。
char ch;
while((ch=getchar())!='0')
{ i=0;
while (i<&&ch!=[i])
i++;
if
(i>=)
Error(
else
printf(
}
printf(
}
4.8
写一算法
void
StrReplace(char *T, char *P, char *S),
将
T
中首次出现
的子串
替换为串
S
。
注意:
S
和
P
的长度不一定相等。
可以使用已有的串操作。
解:由于
S
和
P
p>
的长度不一定相等,所以在替换时可能要移动字符元素。我们可以用到前
void StrReplace (char *T, char *P, char
*S)
{//
串替换
int
i , m;
m=strlen
(P);//
取得子串长度
i=StrMatch(T,P)
;//
取得串匹配位置
StrDelete(
T,i,m);//
删除匹配处子串
StrInsert( T, S
,i);//
将
S
串插入到匹配位置处
}
4.9
将
NaveStrMatch
改写为输出目标串中所有与模式串匹配的有效位移。
解:把相应的返回语句改为打印输出就可找到所有匹配位置。改写后如下:
void NaveStrMatch
(SeqString T, SeqString P)
{
int i,j,k;
int
m=;//
模式串长度
int
n=;//
目标串长度
for (i=0;
i
确定合法位移
{
j=0; k=i;
while(j
{
-
-
-
-
-