B2118 验证子串
题源:B2118 验证子串
此题可作为KMP算法的模板题。
题目描述
输入两个字符串,验证其中一个串是否为另一个串的子串。
输入格式
两行,每行一个字符串。
输出格式
若第一个串
s
1
s_1
s1 是第二个串
s
2
s_2
s2 的子串,则输出(s1) is substring of (s2)
;
否则,若第二个串
s
2
s_2
s2 是第一个串
s
1
s_1
s1 的子串,输出(s2) is substring of (s1)
;
否则,输出 No substring
。
样例 #1
样例输入 #1
abc
dddncabca
样例输出 #1
abc is substring of dddncabca
样例 #2
样例输入 #2
aaa
bbb
样例输出 #2
No substring
提示
对于 100 % 100 \% 100% 的数据,字符串长度在 20 20 20 以内。
思路
按照本题的数据规模,使用逐个匹配也可以通过,不过此题也可作为练习KMP算法的模板题,具体实现方法如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define OK 1
#define NO 0
typedef long long LL;
// const int INF = 2e9;
// const double pi = 3.14;
void getNext(char *pattern, int *next) {
int len = strlen(pattern);
int i = 0, j = -1;
next[0] = -1;
while (i < len) {
if (j == -1 || pattern[i] == pattern[j]) {
i++;
j++;
next[i] = j;
} else {
j = next[j];
}
}
}
int kmp(char *text, char *pattern) {
int len1 = strlen(text);
int len2 = strlen(pattern);
int i = 0, j = 0;
int *next = (int *)malloc(sizeof(int) * len2);
getNext(pattern, next);
while (i < len1 && j < len2) {
if (j == -1 || text[i] == pattern[j]) {
i++;
j++;
} else {
j = next[j];
}
}
free(next);
if (j == len2) {
return i - j;
} else {
return -1;
}
}
int main() {
char s1[21], s2[21];
scanf("%s %s", s1, s2);
int len1 = strlen(s1), len2 = strlen(s2);
int p = len1 >= len2;
int f = 0;
if (p) {
if (kmp(s1, s2) != -1) {
printf("%s is substring of %s\n", s2, s1);
f = 1;
}
} else {
if (kmp(s2, s1) != -1) {
printf("%s is substring of %s\n", s1, s2);
f = 1;
}
}
if (!f) {
printf("No substring\n");
}
return 0;
}
小结
如前文所述,本题可作为KMP算法的模板题。
每一个不曾起舞的日子,都是对生命的辜负。