Cod sursa(job #2430925)

Utilizator AxellApostolescu Alexandru Axell Data 17 iunie 2019 12:15:08
Problema Potrivirea sirurilor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.67 kb
#include <iostream>
#include <algorithm>
#include <fstream>
#include <string>
#include <vector>

using namespace std;

int* generateLps(string str) {
	int *lps = new int[str.length()];
	lps[0] = 0;
	int i = 1;  //  Current index in string
	int length = 0;  //  Curent length of prefix
	int N = str.length();  //  Length of the string
	//  String is not done
	while (i < N) {
		//  Match betwen curent position and coresponding prefix position
		if (str[length] == str[i]) {
			length++;
			lps[i] = length;
			i++;
		} else {
			//  if we have already checked for length == 0 we increment index
			if (length == 0) {
				lps[i] = 0;
				i++;
			} else {
				//  This will take us to the first character after the prefix
				//  So we can check if the current char may be put here
				length = lps[length];
			}
		}
	}
	return lps;
}

vector<int> kmp(string str1, string str2, int* lps) {
	vector<int> result;
	int i = 0;  //  index in str1
	int j = 0;	//  index in str2
	while (j < (int)str2.length()) {
		if (str2[j] == str1[i]) {
			i++;
			j++;
			if (i == (int)str1.length()) {
				result.push_back(j - i);
				i = lps[i - 1];
			}
		} else {
			//  Verified with the first letter of str1
			if (i == 0) {
				j++;
			} else {
				i = lps[i - 1];
			}
		}
	}
	return result;
}

int main() {
	ifstream in;
	in.open("strmatch.in");
	ofstream out;
	out.open("strmatch.out");
	if (!in || !out) {
		std::cout << "Problem with opening files!\n";
		return -1;
	}
	string str1, str2;
	in >> str1 >> str2;
	int *arr = generateLps(str1);
	vector<int> v = kmp(str1, str2, arr);
	out << v.size() << endl;
	for (int i = 0 ; i < min((int)v.size(), 1000) ; ++i) {
		out << v[i] << " ";
	}
	delete[] arr;

	return 0;
}