【20分】F. 可重叠子串I)

题目描述

给定一个字符串(模式串)和一些待查找的字符串,求每个待查找字符串在模式串中出现的次数(可重叠)

输入

测试数据有多组(测试组数 <= 5),

第一行包括一个字符串P,长度不超过105,且非空串

第二行包括一个整数N,代表待查找的字符串数量 (1 <= N <= 5)

接下来的N行,每一行包括一个待查找的字符串,其长度不超过50,且非空串

输出

对于每组测试数据,

输出每个待查找字符串出现的次数,

具体输出见样例

样例查看模式
正常显示 查看格式
输入样例1<-复制
aabbcc
3
aa
bb
cc
ababab
1
aba
输出样例1
aa:1
bb:1
cc:1
aba:2
#include<iostream>
#include<cstring>
using namespace std;

int* get_next(string str) {
	int len = (int)str.size();
	int* next = new int[len + 1];
	int j = 0, k = -1;
	next[j] = k;
	while (j < len) {
		if (k == -1 || (str[j] == str[k])) {
			j++; k++;
			next[j] = k;
		}
		else {
			k = next[k];
		}
	}
	return next;
}

int KPMIndex(string m, string z) {
	int j = 0, k = 0;
	int* next = get_next(z);
	while (j < (int)m.size() && k < (int)z.size()) {
		if (k == -1 || m[j] == z[k]) {
			j++; k++;
		}
		else {
			k = next[k];
		}
	}
	if (k == (int)z.size()) {
		return j - k + 1;
	}
	else {
		return 0;
	}
}

int cishu(string m, string z) {
	int len_m = (int)m.size();
	int len_z = (int)z.size();
	int count = 0;
	int index;
	string str = m;
	while (1) {
		if (KPMIndex(str, z) != 0) {
			index = KPMIndex(str, z);
			count++;
			str = str.substr(index, len_m);
		}
		else {
			break;
		}
	}
	return count;
}

int main() {
	string str;
	while (cin >> str) {
		int t;
		cin >> t;
		string* zi = new string[t];
		for (int i = 0; i < t; i++) {
			cin >> zi[i];
			//cout << KPMIndex(str, zi[i]) << endl;
			cout << zi[i] << ":" << cishu(str, zi[i]) << endl;
		}
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值