试题四
【说明】
模式匹配是指给定主串t和子串s,在主串 t 中寻找子串s的过程,其中s称为模式。如果匹配成功,返回s在t中的位置,否则返回-1 。
KMP算法用next数组对匹配过程进行了优化。KMP算法的伪代码描述如下:
在串 t 和串 s 中,分别设比较的起始下标 i=j=0。
如果串 t 和串 s 都还有字符,则循环执行下列操作:
(1)如果 j=-1 或者 t[i]=s[j] ,则将 i 和 j 分别加1,继续比较 t 和 s 的下一个字符;
(2)否则,将j向右滑动到 next[j] 的位置,即 j =next[j]。
如果 s 中所有字符均已比较完毕,则返回匹配的起始位置(从1开始);否则返回-1.
其中,next数组根据子串s求解。求解next数组的代码已由get_next函数给出。
【C代码】
(1)常量和变量说明
t,s:长度为ls的字符串
next:next数组,长度为ls
(2)C程序
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
//求next[]的值,
void get_next(int * next, char * s, int ls) {//ls:next数组的长度
int i = 0,j = -1;
next[0] = -1;
/*初始化next[0]*/
while (i < ls) {
/*还有字符*/
if (j == -1 || s[i] == s[j]) {
/*匹配*/
j++;
i++;
if (s[i] == s[j])
next[i] = next[j];
else
next[i] = j;
}
else j = next[j];
}
}
int kmp(int * next, char * t, char * s, int lt, int ls) {
int i = 0, j = 0;
while (i < lt && j<ls) {//填空1
if (j == -1 || t[i]==s[j]) {//填空2
i++;
j++;
}
else {//填空3
get_next(next,s,ls);
j=next[j];
}
}
if (j >= ls)
return i+1-ls;//填空4
else
return -1;
}
【问题1】(8分)
根据题干说明,填充C代码中的空(1)~(4).
【问题2】(2分)
根据题干说明和C代码,分析出kmp算法的时间复杂度为(5)(主串和子串的长度分别为It和Is,用O符号表示)。
【问题3】(5分)
根据C代码,字符串“BBABBCAC”的next数组元素值为(6)(直接写素值,之间用逗号隔开)。若主串为“AABBCBBABBCACCD”,子串为“BBABBCAC”,则函数Kmp的返回值是(7)。
试题六
阅读下列说明和java代码,将应填入 (n) 处的字句写在答题纸的对应栏内。
【说明】
某发票(lnvoice)由抬头(Head)部分、正文部分和脚注(Foot)部分构成。现采用装饰(Decorator)模式实现打印发票的功能,得到如图6-1所示的类图。
【java代码】
class Invoice{ //发票类
public void printInvoice(){
System.out.println("This is the content of the invoice!");
}
}
class Decorator extends Invoice{
protected Invoice ticket;
public Decorator(Invoice t) {//构造方法
this.ticket = t;
}
@Override
public void printInvoice() {
if (ticket!=null){
ticket.printInvoice(); //填空1
}
}
}
class HeadDecorator extends Decorator{
public HeadDecorator(Invoice t) {
super(t);
}
@Override
public void printInvoice() {
System.out.println("This is the header of the invoice! ");
ticket.printInvoice(); //填空2
}
}
class FootDecorator extends Decorator{
public FootDecorator(Invoice t) {
super(t);
}
@Override
public void printInvoice() {
ticket.printInvoice(); //填空3
System.out.println("This is the foot of the invoice! ");
}
}
public class InvoiceTest {
public static void main(String[] args) {
Invoice t = new Invoice();//定义一个发票
Invoice ticket;
ticket = new FootDecorator(new HeadDecorator(t)); //填空4
ticket.printInvoice();
System.out.println("---------------------");
ticket=new FootDecorator(new HeadDecorator(new Decorator(null))); //填空5
ticket.printInvoice();
}
}
//输出结果:
//This is the header of the invoice!
//This is the content of the invoice!
//This is the foot of the invoice!
//---------------------
//This is the header of the invoice!
//This is the foot of the invoice!