Cod sursa(job #2181614)

Utilizator 24601Dan Ban 24601 Data 21 martie 2018 19:20:41
Problema Potrivirea sirurilor Scor 0
Compilator c Status done
Runda Arhiva educationala Marime 2 kb
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>

#define CHUNK (1 << 22)
#define OCHUNK (1 << 13)
#define SIZE 2000000
#define LIM 1000

static char *buf, obuf[OCHUNK];
static size_t pi[SIZE+1], s[LIM];
static size_t oblen = 0;

static void write_int(size_t n, char end)
{
    size_t x, pf = 0;

    if (n == 0) {
            obuf[oblen++] = '0';
            obuf[oblen++] = end;
            return;
        }

    for (x = 1000000; x > 0; x /= 10) {
            if (n / x > 0) {
                    pf = 1;
                }

                if (pf) {
                        obuf[oblen++] = '0' + n / x;
                    }
            n = n % x;
        }

    obuf[oblen++] = end;
}

int main(void)
{
    size_t bsz, i, k, plen, tlen, n = 0, tst;
    char *p, *t;

    freopen("strmatch.in", "r", stdin);
    freopen("strmatch.out", "w", stdout);

    buf = mmap(NULL, CHUNK, PROT_READ, MAP_PRIVATE, open("strmatch.in", O_RDONLY), 0);

    /*bsz = (size_t) read(0, buf, CHUNK);*/
    for (plen = 0; buf[plen] != '\n'; plen++)
        ;
    tst = plen + 1;
    tlen = bsz - tst;
    p = buf - 1;
    t = buf + tst - 1;

    if (plen + 1 == tlen) {
        if (memcmp(p + 1, t + 1, plen)) {
            puts("0");
        } else {
            puts("1\n0");
        }

        return 0;
    }

    pi[1] = 0;
    k = 0;
    for (i = 2; i <= plen; i++) {
        while (k > 0 && p[k + 1] != p[i]) {
            k = pi[k];
        }

        if (p[k + 1] == p[i]) {
            k++;
        }

        pi[i] = k;
    }

    k = 0;
    for (i = 1; i <= tlen; i++) {
        while (k > 0 && p[k + 1] != t[i]) {
            k = pi[k];
        }

        if (p[k + 1] == t[i]) {
            k++;
        }

        if (k == plen) {
            if (n < LIM) {
                s[n] = i - plen;
            }

            n++;
        }
    }

    write_int(n, '\n');
    for (i = 0; i < (n < LIM ? n : LIM); i++) {
        write_int(s[i], ' ');
    }

    write(1, obuf, oblen);

    return 0;
}