Cod sursa(job #3159951)

Utilizator Teodor94Teodor Plop Teodor94 Data 22 octombrie 2023 15:53:21
Problema Potrivirea sirurilor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.08 kb
#include <stdio.h>
#include <string.h>

#define MAX_N 2000000

#define BASE 256
#define MOD1 100021
#define MOD2 100007

char str[MAX_N + 1];
int strLength;

char pattern[MAX_N + 1];
int patternLength;

void eraseNewLine(char str[], int& length) {
  if (str[length - 1] == '\n')
    str[--length] = 0;
}

bool cmp(char str[], char pattern[]) {
  int i;

  i = 0;
  while (str[i] && pattern[i] && str[i] == pattern[i])
    ++i;

  return pattern[i] == 0;
}

int main() {
  FILE *fin, *fout;
  fin = fopen("strmatch.in", "r");
  fout = fopen("strmatch.out", "w");

  int i;
  int pHash1, pHash2;
  int hash1, hash2;
  int power1, power2;
  bool patternFound;

  int matches[1000];
  int noMatches, noTotalMatches;

  fgets(pattern, sizeof(pattern), fin);
  patternLength = strlen(pattern);
  eraseNewLine(pattern, patternLength);

  fgets(str, sizeof(str), fin);
  strLength = strlen(str);
  eraseNewLine(str, strLength);

  pHash1 = pHash2 = 0;
  hash1 = hash2 = 0;
  power1 = power2 = 1;
  for (i = 0; i < patternLength; ++i) {
    pHash1 = (pHash1 * BASE + pattern[i]) % MOD1;
    pHash2 = (pHash2 * BASE + pattern[i]) % MOD2;

    hash1 = (hash1 * BASE + str[i]) % MOD1;
    hash2 = (hash2 * BASE + str[i]) % MOD2;

    if (i > 0) {
      power1 = (power1 * BASE) % MOD1;
      power2 = (power2 * BASE) % MOD2;
    }
  }

  noMatches = noTotalMatches = 0;
  i = patternLength;
  while (i <= strLength) {
    patternFound = hash1 == pHash1 && hash2 == pHash2;

    hash1 -= str[i - patternLength] * power1 % MOD1;
    hash2 -= str[i - patternLength] * power2 % MOD2;
    if (hash1 < 0) hash1 += MOD1;
    if (hash2 < 0) hash2 += MOD2;

    hash1 = (hash1 * BASE + str[i]) % MOD1;
    hash2 = (hash2 * BASE + str[i]) % MOD2;

    if (patternFound) {
      ++noTotalMatches;
      if (noMatches < 1000)
        matches[noMatches++] = i - patternLength;
    }

    ++i;
  }

  fprintf(fout, "%d\n", noTotalMatches);
  for (i = 0; i < noMatches; ++i)
    fprintf(fout, "%d ", matches[i]);

  fclose(fin);
  fclose(fout);
  return 0;
}