阅读下列说明和C代码,回答问题1至问题3,将解答写在答题纸的对应栏内。【说明】模式匹配是指给定主串t和子串s,在主串t中寻找子串s的过程,其中s称为模式。如果匹配成功,返回s在t中的位置,否则返回一1。KMP算法用next数组对匹配过程进行了优化。KMP算法的伪代码描述如下:1.在串t和串s中,分别设比较的起始下标i=j=0。2.如果串t和串s都还有字符,则循环执行下列操作:(1)如果j=1或者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:长度为1t和1s的字符串next:next数组,长度为1s(2)C程序#include<stdio.h>#include<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<Is){/*还有字符*/if(j==一1‖s[i]=s[j]){/*匹配*/j++i++;if(s[i]==s[j])next[i]=next[j];elsenext[i]=j;}elsej=next[j];}}int kmp(int*next,Char*t,char*s,int it,int is) { int i=0,j=0;while(i<It&& (1 ){if(j=一1 ‖ (2) ){ i ++; j++; } else (3) , } if ( j>=ls) return (4); else return一1; }
问答题
根据题干说明,填充C代码中的空(1)~(4)。
【正确答案】正确答案:(1)j<1s (2)t[i]=s[j] (3)j=next[j] (4)i-j+1
【答案解析】解析:本题考查算法设计与分析以及用C程序设计语言实现算法的能力。KMP算法是一个非常经典的模式匹配算法。其核心思想是核心思想:匹配过程中字符对不相等时,不需回溯主串,而是利用已经得到的部分匹配结果将模式向右滑动尽可能远的一段距离继续比较。滑动的距离由next数组给出。该算法提出之后,有一些改进的思想,使得next数组的计算有多种方式。本题干不需要考生考虑如何计算next数组,已经直接给出计算该数组的C代码。只需要根据已经计算的next数组进行模式匹配即可。 在C函数kmp中,while循环是判断串s和t是否还有字符,因此空(1)处应填写“j<1s”。根据题干描述,“如果j=-1或者t[i]=s[j],则将i和j分别加1”,则空(2)处填入“t[i]=s[j]”,空(3)处是“否则,将j向右滑动到next[j]的位置,即j=next[j]”的情况,因此填入“j=next[j]”。空(4)处要填返回值,此处应该是能找到模式串的情况,此时i是主串匹配完成后的位置,j是子串的长度,则匹配的起始位置为i一j+1(从1开始)。
问答题
根据题干说明和C代码,分析出KMP算法的时间复杂度为(5) (主串和子串的长度分别为1t和1s,用O符号表示)。
【正确答案】正确答案: (5)O(1t+1s)
【答案解析】解析:在kmp函数中,只有一个while循环,该算法的时间复杂度为O(1t+1s)。
问答题
根据C代码,字符串“BBABBCAC”的next数组元素值为(6) (直接写元素值,之间用逗号隔开)。若主串为“AABBCBBABBCACCD”,子串为“BBABBCAC”,则函数kmp的返回值是(7)。
【正确答案】正确答案:(6)-1,-1,1,一1,一1,2,0,0(7)6
【答案解析】解析:根据C函数get—next,得到“BBABBCAC"的next数组的值为一1,一1,1,一1,一l, 2,0,0。对主串为“AABBCBBABBCACCD”和上述模式串,得到匹配位置为6,这里需要注意的是,位置从1开始。