数据结构题集-第四章-串-基础知识题
第四章基础知识题
- 4.1 空串和空格串
- 4.2 构造串的基本操作
- 4.3 串的基本操作
- 4.4 组合使用串的基本操作
- 4.5 执行函数输出结果
- 4.6 用串的基本操作转化已知字符串
- 4.7 求KMP算法中模式串的next和nextval
- 4.8 已知主串和模式串求KMP算法
- 4.9 求串长的存储密度
4.1 空串和空格串
简述空串和空格串(或称空格符串)的区别。
解:
空串中不存在字符,空格符串里至少有一个空格字符且不含其它字符(ASCII码值为0x20)。
#include<stdio.h>
int main(){char c=(char)0x20;//测试空格字符的ASCII码值printf("%cspace%caround%chere%c\n",c,c,c,c);return 0;
}
4.2 构造串的基本操作
对于教科书4.1节中所述串的各个基本操作,讨论是否可由其他基本操作构造而得?如何构造?
解:
所述操作中的前5中都不能由其他基本操作构造而得。如教科书4.1.2节所述,可由StrLength,SubString和StrCompare实现Index,Replace也可由StrLength,StrAssign,Concat,SubString和Index等实现,其算法如下所示:
void Replace(String &s,String t,String v){k=Index(s,t);if(k){StrAssign(temp,'');n=StrLength(t);m=StrLength(s);while(k){StrAssign(temp,Concat(temp,SubString(s,1,k-1),v));m-=(k-1)-n;StrAssign(s,SubString(s,k+n,m));k=Index(s,t);}StrAssign(s,Concat(temp,s));}
}
4.3 串的基本操作
设s=‘I AM A STUDENT’,t=‘GOOD’,q=‘WORKER’。
求:
StrLength(s)
StrLength(t)
SubString(s,8,7)
SubString(t,2,1)
Index(s,‘A’)
Index(s,t)
Replace(s,‘STUDENT’,q)
Concat(SubString(s,6,2),Concat(t,SubString(s,7,8)))
解:
14
4
‘STUDENT’
‘o’
3
0
‘I AM A WORKER’
‘A GOOD STUDENT’
4.4 组合使用串的基本操作
已知下列字符串
a = ‘THIS’,f = ‘A SAMPLE’,c = ‘GOOD’,d = ‘NE’,b = ‘’,
s = Concat(a,Concat(SubString(f,2,7),Concat(b,SubString(a,3,2)))),
t = Replace(f,SubString(f,3,6),c),
u = Concat(SubString(c,3,1),d),
g = ‘IS’,
v = Concat(s,Concat(b,Concat(t,Concat(b,u)))),
试问:s,t,v,StrLength(s),Index(v,g),Index(u,g)各是什么?
解:
s=‘THIS SAMPLE IS’
t=‘A GOOD’
v=‘THIS SAMPLE IS A GOOD ONE’
Index(v,g)=3
Index(u,g)=0
4.5 执行函数输出结果
试问执行以下函数会产生怎样的输出结果?
void demonstrate(){StrAssign(s,"THIS IS A BOOK");Replace(s,SubString(s,3,7),"ESE ARE");StrAssign(t,Concat(s,"S"));StrAssign(u,"XYXYXYXYXYXY");StrAssign(v,SubString(u,6,3));StrAssign(w,"W");printf("t=%s,v=%s,u=%s",t,v,Replace(u,v,w));
}//demonstrate
解:
t=THESE ARE BOOKS,v=YXY,u=XWXWXW
4.6 用串的基本操作转化已知字符串
已知:s=‘(XYZ)+*’,t=‘(X+Z)*Y’。试利用联接、求子串和置换等基本运算,将s转化为t
解:
s1=SubString(s,3,1)
s2=SubString(s,6,1)
Replace(s,s1,s2)
Concat(s3,s,s1)
Concat(t,SubString(s3,1,5),SubString(s3,7,2))
4.7 求KMP算法中模式串的next和nextval
令s=‘aaab’,t=‘abcabaa’,u=‘abcaabbabcabaacbacba’。试分别求出它们的next函数值和nextval函数值。
解:
#include<stdio.h>
#include<string.h>
/*
char s[5] = "aaab";
char t[8] = "abcabaa";
char u[21] = "abcaabbabcabaacbacba";
*/
char ss[3][21]={"aaab","abcabaa","abcaabbabcabaacbacba"};
int next[23] = {0};
int nextval[23] = {0};int get_next(char *T){int i,j,len;i=0;j=-1;len = strlen(T);next[0]=-1;while(i<len){if(j==-1||T[i]==T[j])next[++i] = ++j;else j=next[j];}return len;
}int get_nextval(char *T){int i,j,len;i=0;j=-1;len = strlen(T);nextval[0]=-1;while(i<len){if(j==-1||T[i]==T[j]){++i; ++j;if(T[i] != T[j]) nextval[i] = j;else nextval[i] = nextval[j];}else j=nextval[j];}return len;
}
int main(){int i,j,len;for(i=0;i<3;i++){len=get_next(ss[i]);//可适当调整表格视图,以顺利显示在cmd窗口中printf("j ");for(j=1;j<=len;j++) printf("|%3d ",j);printf("\n");for(j=1;j<=10+len*5;j++) printf("-");printf("\n");printf("ss[%d] ",i);for(j=0;j<len;j++) printf("|%3c ",ss[i][j]);printf("\n");for(j=1;j<=10+len*5;j++) printf("-");printf("\n");printf("next[j] ");for(j=0;j<len;j++) printf("|%3d ",next[j]);printf("\n");for(j=1;j<=10+len*5;j++) printf("-");printf("\n");len=get_nextval(ss[i]);printf("nextval[j]");for(j=0;j<len;j++) printf("|%3d ",nextval[j]);printf("\n\n\n\n");}return 0;
}
通过以上程序得到的结果中的每项都加1就可以匹配书籍答案里人工计算出的数值。
结果如图:
4.8 已知主串和模式串求KMP算法
已知主串s=‘ADBADABBAABADABBADADA’,
模式串pat=‘ADABBADADA’,
写出模式串的nextval函数值,并由此画出KMP算法匹配的全过程。
解:
#include<stdio.h>
#include<string.h>
#define LEN 21
#define N 10
char S[LEN+1] = "ADBADABBAABADABBADADA";
char T[N+1] = "ADABBADADA";
int nextval[N+1];int get_nextval(){int i,j,len;i=0;j=-1;len = strlen(T);nextval[0]=-1;while(i<len){if(j==-1||T[i]==T[j]){++i; ++j;if(T[i] != T[j]) nextval[i] = j;else nextval[i] = nextval[j];}else j=nextval[j];}return len;
}
int kmp(int pos){ //0<=pos<LENint i,j,len,slen;i = pos;j = 0;len = strlen(T);slen = strlen(S);while(i<slen && j<len){if(j==-1 || S[i]==T[j]){++i;++j;}else j = nextval[j];printf("%d,%d\n",i,j);}if(j>=len) return i-len;else return -1;
}int main(){int j,len;len=get_nextval(T);printf("j ");for(j=1;j<=len;j++) printf("|%3d ",j);printf("\n");for(j=1;j<=10+len*5;j++) printf("-");printf("\n");printf("pat ");for(j=0;j<len;j++) printf("|%3c ",T[j]);printf("\n");for(j=1;j<=10+len*5;j++) printf("-");printf("\n");printf("nextval[j]");for(j=0;j<len;j++) printf("|%3d ",nextval[j]);printf("\n\n\n\n");printf("match pos %d\n",kmp(0));return 0;
}
运行程序后可以写出模式串的nextval函数值,由于时间的关系,只提供了KMP算法的代码,画的过程以后有机会再补充。
4.9 求串长的存储密度
在以链表存储串值时,存储密度是结点大小和串长的函数。假设每个字符占一个字节,每个指针占4个字节,每个结点的大小为4的整数倍。已知串长的分布函数为f(l)且∑l=0maxlenf(l)\sum_{l=0}^{maxlen}{f(l)}∑l=0maxlenf(l),求结点大小为4k,串长为l时的存储密度d(4k,l)(用公式表示)。
解:
d(4k,l)=l4(k+1)∙[l4k]d(4k,l)=\frac{l}{4(k+1)\bullet\left[\frac{l}{4k}\right]}d(4k,l)=4(k+1)∙[4kl]l
具体的计算步骤正在进行中…