Cod sursa(job #1292429)

Utilizator Mihai96Saru Mihai Mihai96 Data 14 decembrie 2014 12:49:49
Problema Potrivirea sirurilor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.87 kb
#include <fstream>
#include <string>
#include <vector>

using namespace std;

const int MAX_NR_POZITII = 1000;
const char NUME_FISIER_INTRARE[] = "strmatch.in";
const char NUME_FISIER_IESIRE[] = "strmatch.out";

vector<int> *failureTable(const string &tipar){
	vector<int>* failure_table = new vector<int>(tipar.size());
	
	(*failure_table)[0] = 0;
	int len = 0;
	for(int i = 1; i < tipar.size(); ++i){
		if(tipar[i] == tipar[len]){
			++len;
			(*failure_table)[i] = len;
		}else if(len > 0){
			len = (*failure_table)[len-1];
			--i; //pentru ca la pasul viitor i-ul sa ramana acelasi (incrementat automat de "for")
		}else{
			(*failure_table)[i] = 0;
		}
		
	}

	return failure_table;
}

vector<int>* searchKMP(int &n, const string &tipar, vector<int>* failure_table, ifstream &fin){
	n = 0; // numarul de aparitii
	vector<int>* pozitii = new vector<int>(MAX_NR_POZITII);
	int i = 0, j = 0;
	char c;
	bool next = true;
	
	fin >> c;
	while(!fin.eof()){
		if(c == tipar[j]){
			++j;
			if(j == tipar.size()){
				if(n < 1000){
					(*pozitii)[n] = i - tipar.size() + 1;
				}
				++n;

				j = (*failure_table)[j-1];
			}
			fin >> c;
			++i;
		}else{
			if(j > 0){
				j = (*failure_table)[j-1];
			}else{
				fin >> c;
				++i;
			}
		}
	}

	return pozitii;
}

void afiseazaSolutie(const char filename[], int nr_aparitii, vector<int>* pozitii){
	ofstream fout(filename);
	
	fout << nr_aparitii << "\n";
	for(int i = 0; i < nr_aparitii && i < 1000; ++i){
		fout << (*pozitii)[i] << " ";
	}
	fout.close();
}

int main(int argc, char *argv[]){
	string tipar;
	ifstream fin(NUME_FISIER_INTRARE);

	fin >> tipar;
	vector<int>* failure_table;
	failure_table = failureTable(tipar);
	int nr_aparitii;
	vector<int>* pozitii;
	pozitii = searchKMP(nr_aparitii, tipar, failure_table, fin);
	fin.close();

	afiseazaSolutie(NUME_FISIER_IESIRE, nr_aparitii, pozitii);

	delete failure_table;
	delete pozitii;
	return 0;
}