Cod sursa(job #1420068)

Utilizator andrei31Andrei Datcu andrei31 Data 17 aprilie 2015 15:34:05
Problema Potrivirea sirurilor Scor 38
Compilator cpp Status done
Runda Arhiva educationala Marime 1.23 kb
#include <fstream>
#include <vector>
#include <string>


std::vector<int> compute_prefix (const std::string &str)
{
	std::vector<int> result(str.size() + 1, -1);

	for (int i = 0; i < str.size(); ++i) {
		result[i + 1] = result[i] + 1;
		while (result[i + 1] > 0 && str[result[i + 1] - 1] != str[i])
			result[i + 1] = 1 + result[result[i + 1] - 1];
	}
	result[0] = -1;
	return result;
}


void match (const std::string &text, const std::string &str)
{
	int matched_index = 0, match_count = 0;
	std::vector<int> matches, prefixes = compute_prefix(str);

	for (int i = 0; i < text.size(); ++i) {
		if (matched_index == str.size()) {
			match_count++;
			if (match_count < 1000)
				matches.push_back(i - matched_index);
			matched_index = prefixes[matched_index];
		}

		if (text[i] == str[matched_index])
			matched_index++;
		else {
			matched_index = prefixes[matched_index];
			if (matched_index > -1)
				--i;
			else
				matched_index = 0;
		}
	}

	std::ofstream fout ("strmatch.out", std::ios::out);
	fout << match_count << std:: endl;

	for (int i : matches)
		fout << i << " ";
	fout << std::endl;
}

int main()
{
	std::ifstream fin("strmatch.in");
	std::string text, str;
	std::getline(fin, str);
	std::getline(fin, text);
	match(text, str);
	return 0;
}