Cod sursa(job #1211341)

Utilizator OwlreeRobert Badea Owlree Data 22 iulie 2014 13:37:57
Problema Potrivirea sirurilor Scor 2
Compilator c Status done
Runda Arhiva educationala Marime 1.6 kb
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void addAtSignToPattern(char *pattern) {
  int m = strlen(pattern);
  pattern[m + 1] = pattern[m];
  pattern[m] = '@';
}

int *computeNextForPattern(char *pattern) {
  int m = strlen(pattern);

  int *next = (int *) malloc (m);
  memset(next, 0, sizeof(pattern));

  int j = 0, t = -1; next[0] = -1;

  while (j < m) {
    while (t > -1 && pattern[j] != pattern[t]) {
      t = next[t];
    }
    t += 1; j += 1;
    if (pattern[j] == pattern[t]) {
      next[j] = next[t];
    } else {
      next[j] = t;
    }
  }

  return next;
}

int findMatchesInText(char *text, char *pattern, int *next, int *match) {
  int cursor = 0;

  int j = 0;
  int k = 0;

  int n = strlen(text);
  int m = strlen(pattern);

  while (j < m && k < n) {
    while (j > -1 && text[k] != pattern[j]) {
      j = next[j];
    }
    k += 1; j += 1;
    if (j == m - 1) {
      match[cursor++] = k - m + 1;
      j = next[j];
    }
  }

  return cursor;
}

int main()
{
  int i;
  char *pattern = (char *) malloc (2000005);
  char *text    = (char *) malloc (2000005);
  int  *match   = (int  *) malloc (2000005);

  FILE *in =  fopen("strmatch.in", "r");
  FILE *out = fopen("strmatch.out", "w");

  fscanf(in, "%s", pattern);
  fscanf(in, "%s", text);

  addAtSignToPattern(pattern);

  int *next = computeNextForPattern(pattern);
  int count = findMatchesInText(text, pattern, next, match);

  fprintf(out, "%d\n", count);

  int stop = count < 1000 ? count : 1000;
  for (i = 0; i < stop; ++i) {
    fprintf(out, "%d ", match[i]);
  }

  fprintf(out, "\n");

  fclose(in);
  fclose(out);

  return 0;
}