设s是一个长度为5的字符串,其中的字符各不相同,则计算s中互异的非平凡子串(非空且不同于s本身)数目的算式为()。
A.5+4+3+2+1
B.5+4+3+2
C.4+3+2+l
D.4+3+2
A.5+4+3+2+1
B.5+4+3+2
C.4+3+2+l
D.4+3+2
(41)
A.5+4+3+2+1
B.5+4+3+2
C.4+3+2+1
D.4+3+2
● 若字符串s 的长度为 n(n >1)且其中的字符互不相同,则 s 的长度为 2 的子串有 (35) 个。
(35)
A. n
B. n-1
C. n-2
D. 2
试题四(共15分)
阅读下列说明和C代码,回答问题1至问题3,将解答写在答题纸的对应栏内。
【说明】
模式匹配是指给定主串t和子串s,在主串t中寻找子串s的过程,其中s称为模式。
如果匹配成功,返回s在t中的位置,否则返回-1 。
KMP算法用next数组对匹配过程进行了优化。KMP算法的伪代码描述如下:
1.在串t和串s中,分别设比较的起始下标i=J=O
2.如果串t和串s都还有字符,则循环执行下列操作:
(1)如果j=-l或者t[i]-s[j],则将i和j分别加1,继续比较t和s的下一个字符;
(2)否则,将j向右滑动到next[j]的位置,即j =next[J]
3.如果s中所有字符均已比较完毕,则返回匹配的起始位置(从1开始);否则返回一1.
其中,next数组根据子串s求解。求解next数组的代码已由get_next函数给出。
【C代码】
(1)常量和变量说明
t,s:长度为悯铂Is的字符串
next:next数组,长度为Is
(2)C程序
include <stdio.h>
nclude <stdliB.h>
include <string.h>
/*求next【】的值*/
void get_next(int *next, char *s, int Is) {
int i=0,j=-1;
next[0]=-1;/*初始化next[0]*/
while(i< ils){/*还有字符*/
if(j=-1l ls[i]=s[j]){/*匹配*/
j++;
i++;
if(s[i]一s[jl)
next [i]- next[j];
else
Next[i]=j;
}
else
J= next[j];
}
}
int kmp(int *next, char *t ,char *s, int.lt, int Is )
{
inti= 0,j =0 ;
while (i<lt && (1 ) {
if(j=-1 II 2_) {
i++ ;
j ++ ;
} else
(3) :
}
if (j>= ls)
Retum (4)
else .
retum-1;
【问题1】(8分)
根据题干说明,填充C代码中的空(1)~(4).
【问题2】(2分)
根据题干说明和C代码,分析出kmp算法的时间复杂度为 (5)(主串和子的长度分别为It和Is,用O符号表示)。
【问题3】(5分)
根据C代码,字符串“BBABBCAC”的next数组元素值为 (6) (直接写素值,之间用逗号隔开)。若主串为“AABBCBBABBCACCD”,子串为“BBABBCAC则函数Kmp的返回值是 (7)
阅读下列函数说明和C代码,把应填入其中n处的字句写在答卷的对应栏内。
【函数2说明】
本题中的函数encode()和decode()分别实现对字符串的变换和复原。变换函数encode()顺序考察已知字符串的字符,按以下规则逐组生成新字符串:
1.若已知字符串的当前字符不是数字字符,则复制该字符于新字符串中。
2.若已知字符串的当前字符是一个数字字符,且它之后没有后继字符,则简单地将它自己复制到新字符串中。
3.若已知字符串的当前字符是一个数字字符,并且还有后继字符,设该数字字符的面值为n,则将它的后续字符(包括后续字符是一个数字字符)重复复制n+1次到新字符串中。
4.以上述一次变换为一组,在不同组之间另插入一个下划线字符“-”用于分隔。例如。encode()函数对字符串26a3t2的变换结果为666_a_tttt_2
复原函数decode()做变换函数encode()的相反的工作。即复制不连续相同的单个字符,而将一组连续相同的字符(不超过10个)变换成一个用于表示重复次数的数字字符和一个重复出现的字符,并在复原过程中掠过变换函数为不同组之间添加的一个下划线字符。
假定调用变换函数encode()时的已知字符串中不包含下划线字符。
【函数2】
int encode(char*instr,char * outstr)
{
char*ip,*op,c;int k,n;
ip=instr;op=outstr;
while(*ip){
if (1) &&*(ip+1){
n= *ip -'0'+ 1;
c= *++ip;
for(k=0;k<=n;k++)
(2);
}
else (3);
*op++ ='-';
ip++;
}
if(op>outstr) (4);
*op='\0';
return op-outstr;
}
int decode(char * instr,char * outstr)
{char*ip,*op,c;int n;
ip=instr;op=outstr;
while(*ip){
c= *ip;n=0;
while(*ip==c && n<=10){ip++;n++;}
if (5) *op++='0'+n-1;
*op++=c;
if(* ip=='_',) (6);
}
* p='\0';
return op-outstr;
}
关于字符串类型的操作,()的描述是错误的。
A.str.replace(x,y)方法把字符串str中所有的x子串都替换成y
B.想把一个字符串str所有的字符都大写,用str.upper()
C.想获取字符串str的长度,用字符串处理函数str.len()
D.设x=’aa’,则执行x*3的结果是‘aaaaaa’
请编写函数fun(),其功能是:将s所指字符串中除了下标为奇数、同时ASCII值为偶数的字符外,其余的全部删除,串中剩余字符所形成的一个新串放在t所指的数组中。
例如,若s所指字符串中的内容为edB2A4Dsdg,其中字符A的ASCII码值为奇数,因此应当删除;其中字符B的ASCII码值为偶数,但在数组中的下标为偶数,因此也应当删除:而字符2的ASCII码值为偶数,所在数组中的下标为奇数,因此不应当删除,其他依此类推。最后t所指的数组中的内容应是d24。
注意:部分源程序给出如下。
请勿改动主函数main和其他函数中的任何内容,仅在函数fun的花括号中填入所编写的若干语句。
试题程序:
include <conio.h>
include <stdio.h>
include<string, h>
void fun(char*s, char t[])
{
}
main()
{
char s[100] ,t[100];
clrscr();
printf("\nPlease enter string S: ");
scanf("%s",s);
fun(s,t);
printf("\nThe result is: %s\n",t);
}
A、集合
B、数列
C、序列
D、聚合
阅读下列函数说明和C函数,将应填入(n)处的字句写在对应栏内。
【函数2.1说明】
函数palindrome(char s[])的功能是,判断字符串s是否为回文字符串,若是,则返回0,否则返回-1。若一个字符串顺读和倒读都一样时,称该字符串是回文字符串,例如:“LEVEL”是回文字符串,而“LEVAL”不是。
【函数2.1】
int palindrome(char s[ ] )
{ char * pi, * pj;
pi=s; pj=s+strlen(s)-1;
while(pi<pj&&(1)){
pi ++ ;pj --
}
if((2))return -1;
else return 0;
}
【函数2.2说明】
函数f(char * str,char del)的功能是:将非空字符串str分割成若干个子字符串并输出,del表示分割时的标志字符。
例如若str的值为“33123333435”,del的值为“3”,调用此函数后,将输出3个子字符串,分别为“12”、“4”和“5”。
【函数2.2】
void f(char * str, char del)
{ int i ,j ,len;
len = strlen (str)
i=0;
while(i < len) {
while((3))i++; /*忽略连续的标志字符*/
/*寻找从str[i]开始直到标志字符出现的一个子字符串*/
j=i+1;
while(str[j] != del && str[j] ! = '\0')j ++
(4): '\0'; /*给找到的字符序列置字符串结束标志*/
printf("%s\t",&str[i]);
(5);
}
}