Cod sursa(job #2225643)

Utilizator TrixerAdrian Dinu Trixer Data 27 iulie 2018 19:19:26
Problema Potrivirea sirurilor Scor 0
Compilator c Status done
Runda Arhiva educationala Marime 1.54 kb
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define min(a, b) (((a) < (b)) ? (a) : (b))

#define MAXLEN	2000000
#define MAXPOS	1000

int n_matches, pattern_len, text_len;
int matches[MAXPOS];
char *pattern, *text;
int *pmt;

int main(void)
{
	// allocate memory
	pattern = malloc(sizeof(*pattern) * (MAXLEN + 1));
	text = malloc(sizeof(*text) * (MAXLEN + 1));
	pmt = malloc(sizeof(*pmt) * MAXLEN);

	// read input
	freopen("strmatch.in", "r", stdin);
	fgets(pattern, MAXLEN, stdin);
	fgets(text, MAXLEN, stdin);

	pattern_len = strlen(pattern) - 1;
	text_len = strlen(text) - 1;

	// solve
	// generate partial match table
	pmt[0] = 0;

	for (int i = 0, j = 1; j < text_len; j++) {
		// try to use the last prefix
		while (i > 0 && pattern[i] != pattern[j])
			i = pmt[i - 1];

		// if partial match, increment length of prefix
		if (pattern[i] == pattern[j])
			i++;

		// save lenght of prefix
		pmt[j] = i;
	}

	// find matches
	for (int i = 0, j = 0; j < text_len; j++) {
		// try to use the last prefix
		while (i > 0 && pattern[i] != text[j])
			i = pmt[i - 1];

		// if partial match, increment length of prefix
		if (pattern[i] == text[j])
			i++;

		// if match, save the index
		if (i == pattern_len) {
			if (n_matches < 1000)
				matches[n_matches] = j - pattern_len + 1;
			n_matches++;
			i = pmt[i - 1];
		}
	}

	// write output
	freopen("strmatch.out", "w", stdout);
	printf("%d\n", n_matches);
	for (int i = 0; i < min(n_matches, MAXPOS); i++)
		printf("%d ", matches[i]);

	// free memory
	free(pattern);
	free(text);
	free(pmt);

	return 0;
}