Cod sursa(job #1211353)

Utilizator OwlreeRobert Badea Owlree Data 22 iulie 2014 14:30:44
Problema Potrivirea sirurilor Scor 100
Compilator c Status done
Runda Arhiva educationala Marime 1.59 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] = '@';
}

void computeNextForPattern(char *pattern, int *next) {
  int m = strlen(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;
    }
  }
}

int findMatchesInText(char *text, char *pattern, int *next, int *match) {
  int cursor = 0;
  int count  = 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) {
      count++;
      if (cursor < 1000) {
        match[cursor++] = k - m + 1;
      }
      j = next[j];
    }
  }

  return count;
}

int main()
{
  int i;

  char *pattern = (char *)malloc(2000005);
  char *text    = (char *)malloc(2000005);
  
  int  next  [2000005];
  int  match [1005];

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

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

  addAtSignToPattern(pattern);

  computeNextForPattern(pattern, next);

  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;
}