Cod sursa(job #2107717)

Utilizator AlexnolifeAlexandru Ica Alexnolife Data 17 ianuarie 2018 17:26:51
Problema Potrivirea sirurilor Scor 38
Compilator cpp Status done
Runda Arhiva educationala Marime 2.46 kb
#include <fstream>
#include <string>
#include <list>
#include <algorithm>

/*
 * fullstr e sirul intreg
 * substr e subsirul
 */
void Solve(std::string& fullstr, std::string& substr)
{
	std::ofstream outputFile("strmatch.out");
	/* 
	 * Prima data trebuie afisat numarul de aparitii
	 * lista memoreaza pozitiile la care s-a gasit subsirul 
	 */
	std::list<std::size_t> appearance_stream;

	/* Marimea sirului intreg si a subsirului */
	std::size_t fullstrLength = fullstr.size();
	std::size_t substrLength  = substr.size();
	/* De cate ori a aparut subsirul in sir */
	std::size_t numberOfAppearances = 0;

	std::size_t i = 0;
	std::size_t offset = 0; // al catelea caracter compar din subsir
	std::size_t prevPos = 0; // pozitia la care incepe cautarea subsirului

	bool canSetPrevPos = true;

	/* Cat timp sunt in sirul principal */
	while (i < fullstrLength) {
		if (fullstr[i] == substr[offset]) { // daca caracterul la care sunt acum e egal cu cel din subir(initial la indicele 0. Daca e egal atunci offsetul creste pentru a compara caracterul la indexul 1, dupa 2 etc...)
			prevPos = (canSetPrevPos == true) ? i : prevPos; // modific pozitia la care incepe subsirul in sirul principal numai daca nu caut deja in subsir
			canSetPrevPos = false;
			
			if (offset == substrLength - 1) { // daca offsetul e maxim
				appearance_stream.emplace_back(prevPos);
				numberOfAppearances++;

				i = prevPos;
				offset = 0;
			}
			else if (offset < substrLength - 1) {
				offset++;
			}
		}
		else {
			offset = 0;
			/* Du-te inapoi de unde a inceput subsirul */
			if (!canSetPrevPos) { 
				i = prevPos;
			}
			canSetPrevPos = true;
		}

		i++;
	}

	std::size_t index = 0;

	/* Scrie numarul de aparitii */
	outputFile << numberOfAppearances << "\n";
	/* scrie toate pozitiile la care s-a gasit subsirul */
	std::for_each(appearance_stream.begin(),
			      appearance_stream.end(),
		          [&outputFile, &index](const std::size_t& position) { index++; if (index > 1000) outputFile << ""; else outputFile << position << " "; });
}

int main()
{
	std::ifstream inputFile("strmatch.in");

	std::string fullString;
	std::string substring;

	/* lungimea maxima pt siruri e 2 mil caractere */
	fullString.reserve(2000000);
	substring.reserve(2000000);

	/* citeste sirurile */
	std::getline(inputFile, substring);
	std::getline(inputFile, fullString);

	/* Scrie in strmatch.out rezultatele */
	Solve(fullString, substring);
}