赞
踩
int ViolentMatch(char* s, char* p) { int sLen = strlen(s); int pLen = strlen(p); int i = 0; int j = 0; while (i < sLen && j < pLen) { if (s[i] == p[j]) { i++; j++; } else { i = i - j + 1; j = 0; } } if (j == pLen) { return i - j; } else { return -1; } }
-接下来用 S[4] 开头的子串: S[4] = “ababf“ 与 P = “ababf“ 比较。此时,由于 S[4~5] 与 P[0~2] 相同,那以S[4] 为开头的字符串与 P 匹配时,无需从S[4]开始,直接从S[5] 与 P[3] 开始比较即可。比较到S[8] 与 P[5] 的时候,S[8] = P[5],字符串匹配完成,返回起始位置4。
for (int i = 2, j = 0; i <= n; i ++ )
{
while (j && p[i] != p[j + 1])
{
j = ne[j];
}
if (p[i] == p[j + 1])
{
j ++ ;
}
ne[i] = j;
}
题目描述
给定一个字符串 S,以及一个模式串 P,所有字符串中只包含大小写英文字母以及阿拉伯数字。
模式串 P 在字符串 S 中多次作为子串出现。
求出模式串 P 在字符串 S 中所有出现的位置的起始下标。
输入格式
第一行输入整数 N,表示字符串 P 的长度。
第二行输入字符串 P。
第三行输入整数 M,表示字符串 S 的长度。
第四行输入字符串 S。
输出格式
共一行,输出所有出现位置的起始下标(下标从 0 开始计数),整数之间用空格隔开。
数据范围
1 ≤ N ≤ 1e5
1 ≤ M ≤ 1e6
输入样例
3
aba
5
ababa
输出样例
0 2
#include <bits/stdc++.h> using namespace std; const int N = 100010, M = 1000010; int n, m; int ne[N]; char s[M], p[N]; int main() { cin >> n >> p + 1 >> m >> s + 1; // 求ne过程 for (int i = 2, j = 0; i <= n; i ++ ) { while (j && p[i] != p[j + 1]) { j = ne[j]; } if (p[i] == p[j + 1]) { j ++ ; } ne[i] = j; } // kmp匹配过程 for (int i = 1, j = 0; i <= m; i ++ ) { while(j && s[i]!= p[j+1]) //如果不匹配 j表示退无可退了 { j = ne[j]; //表示j退几步 } if(s[i] == p[j+1]) //如果他俩已经匹配了 { j++; //就可以移动到下一个位置 } if(j == n) //匹配成功 { cout << i-n << ' '; //i-n+1是下标, 但是题意从0开始, 所以还有减去1 j = ne[j]; } } system("pause"); return 0; }
#include <bits/stdc++.h> using namespace std; const int N = 1000010; int n, m; char s[N], p[N]; int ne[N]; int main() { cin >> m >> p >> n >> s; ne[0] = -1; for (int i = 1, j = -1; i < m; i ++ ) { while (j >= 0 && p[j + 1] != p[i]) { j = ne[j]; } if (p[j + 1] == p[i]) { j ++ ; } ne[i] = j; } for (int i = 0, j = -1; i < n; i ++ ) { while (j != -1 && s[i] != p[j + 1]) { j = ne[j]; } if (s[i] == p[j + 1]) { j ++ ; } if (j == m - 1) { cout << i - j << ' '; j = ne[j]; } } system("pause"); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。