Cod sursa(job #2067903)

Utilizator AlexandruLuchianov1Alex Luchianov AlexandruLuchianov1 Data 16 noiembrie 2017 22:37:45
Problema Potrivirea sirurilor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.86 kb
#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <climits>

using namespace std;

ifstream in("strmatch.in");
ofstream out("strmatch.out");

typedef unsigned long long ull; //asta e numai pentru hash-uri cand vrei sa aproximezi solutia, cand nu gasesti rezolvare analitica

int const nmax = 2000000;
ull const base = 47;

string s1, s2;
ull hash2[nmax];

int main() {
  /*
  ull i = 0;
  ull j = i - 1u;  //cel mai mare numar care poate fi reprezentat
  cout << i << " " << j << " " << (((ull)LONG_LONG_MAX) * 2 + 1) << endl;
  ull k = j * j; //(2^64 - 1) ^ 2 = 2^128 - 2^65 + 1 = 1 - 2^65 = 0 - (2^65 - 1) = 111..1111 - (1111..11111 - 1) = 1
  //te poti baza pe unsinged long long ca fiind un modulo 2^64. Numai ca e mai rapid decat modulo
  //conform standardului C++, ar trebui sa fie reliable
  cout<< k;
  */

  //putem implementa foarte comod hash-uri pe unsinged long long
  in >> s1 >> s2;
  int n1 = s1.size();

  ull needle = 0;
  ull basep = 1;
  for(int i = 0 ; i < n1; i++) {
    needle = needle * base + (s1[i] - 'A');
    basep = basep * base;
  }
  hash2[0] = (s2[0] - 'A');
  for(int i=1; i<s2.size(); i++) {
    hash2[i] = hash2[i-1] * base + (s2[i] - 'A');
  }
  int nsol = 0;
  vector<int> sol;
  ull h = hash2[n1 - 1];  //de la 0 pana la n1 - 1
  if(h == needle) {
    nsol++;
    if(nsol <= 1000)
      sol.push_back(0);
  }
  for(int i = n1; i < s2.size(); i++) {
    //de la i - n1 + 1 pana la i
    h = hash2[i] - hash2[i - n1] * basep; // s[0] * b ^ i - s[0] z
    if(h == needle) {
      nsol++;
      if(nsol <= 1000)
        sol.push_back(i - n1 + 1);
    }
  }
  out<< nsol << '\n';
  for(int i = 0; i < sol.size(); i++) {
    out << sol[i] << " ";
  }

  //hash2[0] = s[0]
  //hash2[1] = s[0] * b + s[1]
  //hash2[2] = s[0] * b^2 + s[1] * b + s[2]
  return 0;
}