Cod sursa(job #2086422)

Utilizator valinetromaniaValiNet Romania valinetromania Data 12 decembrie 2017 02:31:37
Problema Potrivirea sirurilor Scor 14
Compilator c Status done
Runda Arhiva educationala Marime 2.94 kb
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define STRINGLENGTH       2000002
#define PATTERNLENGTH      2000002

typedef char* string;
typedef size_t bool;

char text[STRINGLENGTH];
char pattern[PATTERNLENGTH];
size_t out[PATTERNLENGTH];

#define BASE 3
#define PRIME 101

#define TRUE 1
#define FALSE 0

/* Static inline necesita trecerea la C99 sau gnu89 */
static inline __attribute__((always_inline)) 
size_t hash(string text, int pos, int length)
{
	size_t S = 0, i;
	for (i = pos; i < length + pos; ++i) {
		S = (S * BASE + text[i]) % PRIME;
	}
	return S;
}

int power(int b, int e) {
    int r = 1;
    size_t i;
    for (i = 0; i < e; i++) {
        r = (r * b) % PRIME;
    }
}

int main(int argc, char** argv)
{
	size_t strlens;
    size_t strlenp;
    int output[1000];
    size_t i, j, t, match = 0, y = 0;
    if (freopen("strmatch.in", "r", stdin) == NULL) {
		return -1;
	}
    if (freopen("strmatch.out", "w", stdout) == NULL) {
		return -1;
	}
    if (fgets(pattern, STRINGLENGTH, stdin) == NULL) {
		return -1;
	}
    strlenp = strlen(pattern);
    if (pattern[strlenp - 1] == '\n') {
        pattern[strlenp - 1] = '\0';
        strlenp--;
    }
    if (fgets(text, STRINGLENGTH, stdin) == NULL) {
		return -1;
	}
    strlens = strlen(text);
    if (text[strlens - 1] == '\n') {
        text[strlens - 1] = '\0';
        strlens--;
    }
    if (strlenp > strlens)
    {
        printf("0\n");
        return 0;
    }
    bool was;

    int H = hash(text, 0, strlenp);

		/* Calcularea hash-ului pattern-ului */
		int hashp = hash(pattern, 0, strlenp);

		int max_power = power(BASE, strlenp - 1);

        if (H == hashp) {
				was = TRUE;
				for (j = 0; j < strlenp; j++)
				{
					if (text[i + j] != pattern[j]) {
                        was = FALSE;
                        break;
                    }
				}
				if (was)
				{
                    if (y < 1000) {
					output[y] = i;
					y++;
				    }
                    match++;
				}
				was = FALSE;
        }


		for (i = 1; i < strlens; i++) {

			if (i < strlens) {
				H = (((H - (text[i - 1] * max_power)) % PRIME) + PRIME);
				H = H * BASE;
				H = H + text[i + strlenp - 1];
				H = H % PRIME;
				//if (H < 0) H = H + PRIME;
			}
 			if (H == hashp) {
				was = TRUE;
                char temp = text[i + 1];
                text[i + 1] = '\0';
                was = !strcmp(text + i - strlenp + 1, pattern);
                text[i + 1] = temp;
				/*for (j = 0; j < strlenp; j++)
				{
					if (text[i + j] != pattern[j]) {
                        was = FALSE;
                        break;
                    }
				}*/
				if (was)
				{
                    if (y < 1000) {
					output[y] = i - strlenp + 1;
					y++;
				    }
                    match++;
				}
				was = FALSE;
			}
		}

	printf("%d\n", match);
	if (match > 1000) {
		match = 1000;
	}
	for (t = 0; t < match; t++) {
		printf("%d ", output[t]);
	}
	printf("\n");
	fclose(stdin);
	fclose(stdout);

	return 0;
}