Cod sursa(job #2166336)

Utilizator AlexnolifeAlexandru Ica Alexnolife Data 13 martie 2018 16:39:51
Problema Potrivirea sirurilor Scor 2
Compilator cpp Status done
Runda Arhiva educationala Marime 1.6 kb
#include <fstream>
#include <string>
#include <array>
#include <iostream>

void Read(std::string& substring, std::string& fullstring)
{
	std::ifstream f("strmatch.in");
	
	std::getline(f, substring);
	std::getline(f, fullstring);

	std::cout << substring << '\n' << fullstring << '\n';
}

std::array<int, 1000020U> prefix;

void MakePrefix(const std::string& substring)
{
	size_t i, j = 0U;

	for(i = 1U; i < substring.size();) {
		if(substring[j] == substring[i]) {
			prefix[i] = j + 1;

			++i, ++j;
		}
		else if(j > 0U) {
			j = prefix[j - 1U];
		}
		else {
			prefix[i] = 0;
		}
	}
}

std::array<size_t, 1010U> index;
size_t lastIndex = 0U;

void KMP(const std::string& substring, const std::string& fullstring)
{
	size_t i, offset = 0U;

	for(i = 0U; i < fullstring.size();) {
		if(substring[offset] != fullstring[i]) { // no matching, start over with searching
			if(offset > 0U) 
				offset = prefix[offset - 1U];
			else
				++i;
		}
		else if(substring[offset] == fullstring[i] && offset != substring.size() - 1U) { // characters match but we didn't find the pattern yet
			++i, ++offset;
		}
		else { // we found the match
			if(lastIndex < 1000U)
				index[lastIndex++] = i - offset;	
			else 
				break;

			if(offset > 0U)
				offset = prefix[offset - 1U];
		}
	}
}

void PrintIndex()
{
	std::ofstream g("strmatch.out");

	g << lastIndex << '\n';

	for(size_t i = 0U; i < lastIndex; ++i) {
		g << index[i] << ' ';
	}
}

int main(int argc, char * argv[])
{
	std::string fullstring, substring;

	Read(substring, fullstring);
	MakePrefix(substring);
	KMP(substring, fullstring);
	PrintIndex();
	
	std::cin.get();

	return 0;
}