Cod sursa(job #2444835)

Utilizator stoianmihailStoian Mihail stoianmihail Data 1 august 2019 16:28:50
Problema Potrivirea sirurilor Scor 80
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.3 kb
#include <iostream>
#include <fstream>
#include <cstring>
//---------------------------------------------------------------------------
using namespace std;
//---------------------------------------------------------------------------
#define MAX_N 2000000
#define MAX_COUNT 1000
//---------------------------------------------------------------------------
unsigned length, n, countMatches;
char pattern[MAX_N + 2];
char str[MAX_N + 2];
unsigned matches[MAX_COUNT];
unsigned psi[MAX_N + 2];
//---------------------------------------------------------------------------
void compressPi()
// compress pi[] and create two new arrays: psi[] and omega[]
// description in README
{  
  // Initialize the first values
  // 0 is the first state. At this step it receives 2 sons
  psi[0] = 0;
  psi[1] = 0;
  // Compute pi and psi
  unsigned k = 0;
  for (unsigned q = 1; q < length; ++q) {
    // Compute psi
    while ((k > 0) && (pattern[q] != pattern[k])) {
      k = psi[k];
    }
    if (pattern[q] == pattern[k]) {
      k++;
    }
    // Compress possible path
    // For understandability reasons, keep the formula like this
    // TODO: it could be replaced by: (pattern[q + 1] == pattern[k]) ? psi[k] : k
    psi[q + 1] = (pattern[q + 1] == pattern[k]) ? psi[k] : k;
  }
}
//---------------------------------------------------------------------------
void search()
// checks if the pattern can be found in str
{
  if (length > n)
    return;
  unsigned q = 0; // current state
  for (unsigned index = 0; index < n; ++index) {
    // Search only on psi now
    while ((q > 0) && (str[index] != pattern[q]))
      q = psi[q];
    if (str[index] == pattern[q]) {
      ++q;
    }
    // Found?
    if (q == length) {
      if ((countMatches++) != MAX_COUNT) {
        matches[countMatches - 1] = index - length + 1;
      }
    }
  }
}
//---------------------------------------------------------------------------
int main(void) {
  std::ifstream in("strmatch.in");
  in >> pattern >> str;
  in.close();
  
  length = strlen(pattern);
  n = strlen(str);
  
  compressPi();
  search();
  
  std::ofstream out("strmatch.out");
  out << countMatches << endl;
  unsigned lim = (countMatches < MAX_COUNT) ? countMatches : MAX_COUNT;
  for (unsigned index = 0; index < lim; ++index) 
    out << matches[index] << " ";
  out << endl;
  out.close();
  return 0;
}