Cod sursa(job #2224201)

Utilizator razviii237Uzum Razvan razviii237 Data 23 iulie 2018 13:55:56
Problema Potrivirea sirurilor Scor 16
Compilator cpp Status done
Runda Arhiva educationala Marime 1.84 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];

struct result
{
    int x, y;
}rez[maxn];
int k;

void prefix_calculate(char p[], int prefix[])
{
    int i, a;
    int n = strlen(p);
    prefix[0] = 0;
    a = 0;
    for(i = 1; i < n; i ++)
    {
        if(p[i] == p[a])
            ++a;
        else
            a = 0;
        prefix[i] = a;
    }
}

void kmp(char p[], int prefix[], char t[])
{
    int m = strlen(p), n = strlen(t);
    int i, a, b;
    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, i};

                    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);
    //cout << "p size: " << strlen(p) << '\n';
    fs(f, "%s", t);
    //cout << "t size: " << strlen(t) << '\n';

    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].x);

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