Cod sursa(job #2224365)

Utilizator razviii237Uzum Razvan razviii237 Data 23 iulie 2018 20:21:35
Problema Potrivirea sirurilor Scor 16
Compilator cpp Status done
Runda Arhiva educationala Marime 1.75 kb
#include <iostream>
#include <cstdio>
#include <cstring>

#define fs fscanf
#define fp fprintf

using namespace std;
const int maxn = 2e6+5;

FILE *f, *g;

char p[maxn], t[maxn];
int prefix[maxn];

int rez[maxn];
int k;

void prefix_calculate(char p[], int prefixx[])
{
    int i, a;
    int n = strlen(p);
    prefixx[0] = 0;
    a = 0;
    for(i = 1; i < n; i ++)
    {
        while(a > 0 && p[a] != p[i])
            a = prefixx[a-1];
        if(p[i] == p[a])
            ++a;
        prefixx[i] = a;
    }
}

void kmp(char p[], int prefix[], char t[])
{
    int m = strlen(p), n = strlen(t);
    int i, a;
    a = 0;
    for(i = 0; i < n; i ++){
        if(t[i] == p[a])
        {
            ++a;
            if(a == m)
                {
                    //fp(g, "Start: %d, End: %d\n", i - m + 1, i);
                    rez[++k] = i-m+1;

                    if(prefix[a-2] == 0 && prefix[a-1] != 0)
                        a = 1;
                    else
                    {
                        i = i - prefix[a - 2];
                        a = (prefix[a - 2] == 0 ? 0 : 1);
                    }
                }
        }
        else
        {
            if(prefix[a - 1] > 0)
            {
                i = i - prefix[a - 1];
                a = 1;
            }
            else
            a = 0;
        }
    }
}

int main()
{
    f = fopen("strmatch.in", "r");
    g = fopen("strmatch.out", "w");

    fs(f, "%s", p);
    fs(f, "%s", t);

    prefix_calculate(p, prefix);
    kmp(p, prefix, t);

    fp(g, "%d\n", k);
    int file_min = min(k, 1000);
    for(int i = 1; i <= file_min; i ++)
        fp(g, "%d ", rez[i]);

    fclose(f);
    fclose(g);
    return 0;
}