Cod sursa(job #1611225)

Utilizator stoianmihailStoian Mihail stoianmihail Data 23 februarie 2016 23:30:11
Problema Potrivirea sirurilor Scor 100
Compilator c Status done
Runda Arhiva educationala Marime 1.79 kb
#include <stdio.h>
#include <string.h>

#define FP 32051994
#define SP 32051969
#define Nadejde 2000000
#define Smerenie 1000
#define UTF8 256
#define BASE 67

typedef struct {
  int f, s;
} cell;

int N, M, lim, count;
char s[Nadejde + 2];
char p[Nadejde + 2];
int code[UTF8];
int ss, stack[Smerenie + 1];

cell find, search;
cell bases[Nadejde + 2];

void init() {
  int curr = 0;
  char c;

  for (c = 'a'; c <= 'z'; c++) {
    code[c] = curr++;
  }
  for (c = 'A'; c <= 'Z'; c++) {
    code[c] = curr++;
  }
  for (c = '0'; c <= '9'; c++) {
    code[c] = curr++;
  }
}

void getBases() {
  int i;

  bases[0].f = bases[0].s = 1;
  for (i = 1; i <= Nadejde; i++) {
    bases[i].f = (bases[i - 1].f * BASE) % FP;
    bases[i].s = (bases[i - 1].s * BASE) % SP;
  }
}

void append(cell *H, int x) {
  H -> f = ((H -> f * BASE) + x) % FP;
  H -> s = ((H -> s * BASE) + x) % SP;
}

void erase(cell *H, int x) {
  H -> f = ((H -> f - (bases[lim].f * x)) % FP + FP) % FP;
  H -> s = ((H -> s - (bases[lim].s * x)) % SP + SP) % SP;
}

void try(int pos) {
  if ((search.f == find.f) && (search.s == find.s)) {
    count++;
    if (ss < Smerenie) {
      stack[ss++] = pos - lim;
    }
  }
}

int main(void) {
  int i;
  FILE *f = fopen("strmatch.in", "r");

  init();
  getBases();
  
  fscanf(f, "%s%s", p, s);
  fclose(f);

  N = strlen(s);
  M = strlen(p);

  for (i = 0; i < M; i++) {
    append(&find, code[p[i]]);
  }
  for (lim = M - 1, i = 0; i < lim; i++) {
    append(&search, code[s[i]]);
  }
  for (; i < N; i++) {
    append(&search, code[s[i]]);
    try(i);
    erase(&search, code[s[i - lim]]);
  }

  freopen("strmatch.out", "w", stdout);
  fprintf(stdout, "%d\n", count);
  for (i = 0; i < ss; i++) {
    fprintf(stdout, "%d ", stack[i]);
  }
  fclose(stdout);

  /// Multumim Doamne!
  puts("Doamne ajuta!");
  return 0;
}