数据结构实验之串二:字符串匹配
Time Limit: 1000 ms Memory Limit: 65536 KiB
Problem Description
给定两个字符串string1和string2,判断string2是否为string1的子串。
Input
输入包含多组数据,每组测试数据包含两行,第一行代表string1,第二行代表string2,string1和string2中保证不出现空格。(string1和string2大小不超过100字符)
Output
对于每组输入数据,若string2是string1的子串,则输出"YES",否则输出"NO"。
Sample Input
abc a 123456 45 abc ddd
Sample Output
YES YES NO
Hint
Source
赵利强
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<algorithm> #include<iostream> using namespace std; int next[1000002]; void qnext(char *p,int next[]) { int plen = strlen(p); next[0] = -1; int k = -1;//k表示前缀,j表示后缀 int j = 0; while(j <plen - 1) { if(k==-1||p[j] == p[k]) { ++j; ++k; if(p[j]!=p[k]) next[j] = k; else //因为不能出现p[j] = p[ next[j ]], //所以当出现 其 时需要继续递归,k = next[k] = next[next[k]] next[j] = next[k]; } else { k = next[k]; } } } int kmp(char *s,char *p) { int i = 0; int j = 0; int slen = strlen(s); int plen = strlen(p); while(i < slen&& j<plen) { if(j == -1||s[i]== p[j])//j==-1,表明处于一开始,或者完全失配,此时主串下移一位,模式串归零 { i++; j++; } else { j = next[j]; } } if(j == plen) return i-j; else return -1; } int main() { char s[1000002],p[1000002]; while(~scanf("%s%s",s,p)) { qnext(p,next); int o = kmp(s,p); if (o==-1) cout<<"NO"<<endl; else cout<<"YES"<<endl; } }
#include<stdio.h> #include<string.h> void get_next(char str[], int next[]) { int i, j; next[0] = -1; for(i = 1; i < strlen(str); i++) { j = next[i - 1] + 1; while(j > 0 && str[i] != str[j]) { j = next[j - 1] + 1; } if(str[i] == str[j]) { next[i] = j; } else next[i] = -1; } } int KMP(char str1[], char str2[], int next[]) { int i, j; i = 0; j = 0; while(i < strlen(str1) && j < strlen(str2)) { if(str1[i] == str2[j]) { i++; j++; } else { if(j == 0) { i++; } else { j = next[j - 1] + 1; } } } if(j >= strlen(str2)) return 1; else return 0; } int main() { char str2[110], str1[110]; int next[110]; while(~scanf("%s %s", str1, str2)) { get_next(str2, next); if(KMP(str1, str2, next)) printf("YES\n"); else printf("NO\n"); } return 0; }