Cod sursa(job #2378203)

Utilizator puzzleFlutur Vasile puzzle Data 11 martie 2019 20:51:18
Problema Potrivirea sirurilor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.76 kb
#include <fstream>
#include <string>
#include <deque>

std::ifstream in("strmatch.in");
std::ofstream out("strmatch.out");

const int ch = 256; //no characters

void PrintSolutions(std::deque<int>& Solutions)
{
	out << Solutions.size() << '\n';
	while (!Solutions.empty())
	{
		out << Solutions.front() << " ";
		Solutions.pop_front();
	}
}

void Rabin_Karp(std::string& pattern, std::string& text, int primeN)
{
	int i, j;

	int patternLength = pattern.size();
	int textLength = text.size();

	std::deque<int> answers;

	int PatternHash = 0;
	int TextHash = 0;

	int ReHash = 1; 
	for (int i = 0; i < patternLength - 1; i++)
		ReHash = (ReHash * ch) % primeN;
	//ReHash is used when we update the hash window value

	//Calculating the hash value of Pattern and Text
	for (i = 0; i < patternLength; i++)
	{
		PatternHash = (ch * PatternHash + pattern[i]) % primeN;
		TextHash = (ch * TextHash + text[i]) % primeN;
	}

	for (i = 0; i <= textLength - patternLength; i++)
	{
		if (PatternHash == TextHash)
		{
			for (j = 0; j < patternLength; j++)
			{
				if (pattern[j] != text[i + j])
					break;
			}
			if (j == patternLength)
			{
				answers.push_back(i);
			}

		}
		//Calculate hash value for next window of text:
		//Remove leading digit
		//Add trailing digit
		if (i < textLength - patternLength)
		{
			TextHash = (ch * (TextHash - text[i] * ReHash) + text[i + patternLength]) % primeN;

			//We might get negative values for TextHash
			//Convert to positive

			if (TextHash < 0)
				TextHash += primeN;
		}
	}
	PrintSolutions(answers);
}

int main()
{
	std::string pattern;
	in >> pattern;
	
	std::string text;
	in >> text;

	int primeN = 101; //any prime number, key
	Rabin_Karp(pattern, text, primeN);
}