第四章 串答案

巡山小妖精
695次浏览
2021年02月11日 03:51
最佳经验
本文由作者推荐

-

2021年2月11日发(作者:trouble)




第四章



答案



4.1


简述下列每对术语的区别:





空串和空白串;


串常量和串变量;< /p>


主串和子串;


静态分配的顺序串和动态分配的顺序串;

< p>
目标串和模式串;有效位移和无效位移。



答:< /p>


●


空串是指不包含任何字符的串,它的长度为零。





空白串是指包含一个或多个空格的串,空格也是字符。




●


串常量是指在程序中只可引用但不 可改变其值的串。





串变量是可以在运行中改变其值的。




●


主串和子串是相对的,一个串中任意个连续字符组成的串就是 这个串的子串,而包含子


串的串就称为主串。




●


静态分配的顺序串是指串的存储空 间是确定的,即串值空间的大小是静态的,在编译时


刻就被确定。





动态分配的顺序串是在编译时 不分配串值空间,在运行过程中用


malloc


和


free


等函数


根据需要动态地分配和释放字符数组 的空间


(


这个空间长度由分配时确定,也是顺序存储空


间


)


。




●


目标串和模式串

< br>:


在串匹配运算过程中,


将主串称为目标串,

< p>
而将需要匹配的子串称为模


式串,两者是相对的。




●


有效位移和无效位移:在串定位运 算中,模式串从目标的首位开始向右位移,每一次合


法位移后如果模式串与目标中相应的 字符相同,则这次位移就是有效位移


(


也就是从此位置


开始的匹配成功


)


,反之,若有不相同的字符存 在,则此次位移就是无效位移


(


也就是从此位

< 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,



(3)


调用函数


strcmp(s1,s2 )


的返回值是什么


?



(4)


调用函数


strcmp(&s1[5],


的返回值是什么


?


(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>
执行


p=strchr(s2,'6');


之后,


p


的返回值是


NULL


。




(2)strcpy< /p>


函数功能是串拷贝,


strcat


函数的 功能是串联接。所以


:




在执行


strcpy(s3,s1);


后,


s3


的值是




在执行


strcat(s3,


后,


s3


的值变成




在执行完

strcat(s3,s2);


后,


s3

< br>的值就成了




(3)

< p>
函数


strcmp(


串


1


,串


2)


的功能是串比较,按串的大小 进行比较,返回大于


0


,等于


0


或小于


0


的值以表示串


1


比串


2


大,串

< br>1


等于串


2


,串


1


小于串


2


。因此在调用函 数


strcmp(s1,s2)


后,返回值是大于


0


的数


(


字符比较是以


ascii


码值相比的


)







(4)


首先,我们要知道

< p>
&s1[5]


是一个地址,当放在函数


strcm p


中时,它就表示指向以它为


首地址的一个字符串,所以在


strcmp(


&s1[5],


中,前一 个字符串值是



用它和


< br>比较,应该是后者更大,所以返回值是小于


0


的数。




(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

< p>
和


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]));//


设置一个临时串








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

< p>
开始的连续


m


个字符。


若


i≥strlen(S),则没有字符被删除;若


i+m≥st rlen(S),则将


S


中从位置


i< /p>


开


始直至末尾的字符均删去。



解:算法如下:




void StrDelete(char *S, int i ,int m)




{ //


串删除






char Temp[Maxsize];//


定义一个临时串






if(i+m






{







strcpy (Temp, &S[i+m]);//


把删除的字符以后的字符保存到临时串中








strcpy( &S[i],Temp);//


用临时串中的 字符覆盖位置


i


之后的字符







}





else if(i+m>=strlen(S)&& i






{







strcpy(&S[i],


把位置


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


的第

pos


个字符起长度为


len


的子 串。


sub


初始时为一空串







//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;ilength;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





则字符串



被加密为



试写一算法将输入的文本串进行


加密后输出;另写一算法,将输 入的已加密的文本串进行解密后输出。



解:

< br>加密算法可以用两个串中字符的一一对应关系来实现,


当输入一个字符时,


由算法在串


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


中首次出现


的子串

< br>P


替换为串


S


。


注意:


S


和


P


的长度不一定相等。


可以使用已有的串操作。



解:由于


S


和


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








{



-


-


-


-


-


-


-


-