第一题
问:KMP算法是BF算法的改进,是不是说在任何情况下KMP算法的时间性能都比BF算法好?
答:不是,当模式串的next数组中next【0】=-1,而其他元素的值均为0时,KMP算法退化为BF算法。
第二题
问:给出以下模式串的next值和nextval值:abaabaab
答:next值:-1、0、0、1、1、0、3、4
nextval值:-1、0、0、0、1、0、0、4
第三题
问:有一个顺序串s,其字符仅由数字和小写字母组成。设计一个算法将s中所有数字字符放在前半部分,所有小写字母字符放在后半部分。并给出你所设计的算法的时间和空间复杂度。
#include<iostream>
using namespace std;
typedef struct {
char data[100];
int length;
}SqString;
void StrAssign(SqString &s, char cstr[]) {
int i;
for (i = 0; cstr[i] != '\0'; i++) {
s.data[i] = cstr[i];
}
s.length = i;
}
void DispStr(SqString s) {
int i;
if (s.length > 0) {
for (i = 0; i < s.length; i++) {
printf("%c", s.data[i]);
}
printf("\n");
}
}
void Sort(SqString s) {
SqString str;
int m = 0;
for (int i = 0; i < s.length; i++) {
if (48 <= s.data[i] <= 57) {
str.data[m] = s.data[i];
m++;
}
}
for (int i = 0; i < s.length; i++) {
if (97 <= s.data[i] <= 122) {
str.data[m] = s.data[i];
m++;
}
}
DispStr(str);
}
第四题
问:假设字符串s采用顺序串存储,设计一个基于KMP的算法,在串s中查找子串t最后一次出现的位置。例如,当s="abcdabcd",t="abc"时结果为4,当s="aaaaa",t="aaa"时结果为2。
#include<iostream>
using namespace std;
typedef struct {
char data[100];
int length;
}SqString;
void StrAssign(SqString &s, char cstr[]) {
int i;
for (i = 0; cstr[i] != '\0'; i++) {
s.data[i] = cstr[i];
}
s.length = i;
}
int KMP(SqString s, SqString t) {
int next[100], i = 0, j = 0, r = 0;
int result[100];
GetNext(t, next);
while (i < s.length) {
while (i < s.length && j < t.length) {
if (j == -1 || s.data[i] == t.data[j]) {
i++; j++;
}
else
{
j = next[j];
}
}
if (j >= t.length) {
result[r] = i - t.length;
r++;
j == -1;
}
else {
return(-1);
}
}
return(result[r - 1]);
}
第五题
问:假定采用带头结点的单链表保存单词,当两个单词有相同的后缀时,则可共享相同的后缀存储空间,例如,“loading”和“being”,如图4.3所示。设计一个算法找出由str1和str2所指向两个链表共同后缀的起始位置(如图中字符i所在结点的位置p)。
答:构造单词:
查找后缀:
第六题
问:在KMP算法中,计算模式串的next时,当j=0时,为什么要取next[0]=-1?
答:当模式串中0号字符与主串中某字符比较不等时,此时next[0]=-1表示模式串中已没有字符可与主串中的当前字符比较,主串当前指针应后移至下一个字符再和模式串的0号字符进行比较。