Cod sursa(job #2792599)

Utilizator radu.z5Zamfirescu Radu Ioan radu.z5 Data 2 noiembrie 2021 00:12:50
Problema Potrivirea sirurilor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.6 kb
#include <fstream>
#include <vector>

using namespace std;

void buildMismatchTable(vector<int> &p, const string &pattern) {
	// aka sufEnd
	size_t i = 1;
	int prefEnd = -1;
	p[0] = 0;

	while (i < pattern.length()) {
		if (pattern[prefEnd + 1] == pattern[i]) {
			prefEnd++;
			// indexarea e de la 0;
			// in p retin lungimile perechilor de prefix-sufix identice
			p[i] = prefEnd + 1;
			i++;
		} else if (prefEnd == -1) {
			p[i] = 0;
			i++;
		} else {
			prefEnd = p[prefEnd] - 1;
		}
	}
}

bool specialCase(const string &text, const string &pattern, ofstream &out) {
	if (text.size() < pattern.size()) {
		out << "0\n\n";
		return true;
	} else if (text == pattern) {
		out << "1\n0\n";
		return true;
	} else {
		return false;
	}
}

void kmp(const string &text, const string &pattern, ofstream &out) {
	vector<int> p(pattern.size());
	buildMismatchTable(p, pattern);
	vector<int> appsIdx;

	// i = pozitia in sirul mare (text), j = pozitia in sirul mic (pattern)
	size_t i = 0, j = 0;

	while (i < text.size()) {
		if (text[i] == pattern[j]) {
			i++;
			j++;
			if (j == pattern.size()) {
				appsIdx.push_back(i - j);
				j = p[j - 1];
			}
		} else if (j == 0) {
			i++;
		} else {
			j = p[j - 1];
		}
	}

	out << appsIdx.size() << '\n';
	auto threshold = min(appsIdx.size(), (size_t) 1000);
	for (size_t i = 0; i < threshold; i++)
		out << appsIdx[i] << ' ';
	out << '\n';
}

int main(void) {
	ifstream in("strmatch.in");
	ofstream out("strmatch.out");

	string a, b;
	in >> b;
	in >> a;

	kmp(a, b, out);
	in.close();
	out.close();
	return 0;
}