diff options
author | Anton Luka Šijanec <anton@sijanec.eu> | 2024-11-18 00:18:24 +0100 |
---|---|---|
committer | Anton Luka Šijanec <anton@sijanec.eu> | 2024-11-18 00:18:24 +0100 |
commit | 5ddc2e50dcfe5a1e36bb5a04008e29a33a661921 (patch) | |
tree | 50d520ad03f3f267aa7f6504c6e15d9106b97ae6 /šola/aps1/dn/autocomplete/rešitev.cpp | |
parent | aps1dn2: zlivanje (diff) | |
download | r-master.tar r-master.tar.gz r-master.tar.bz2 r-master.tar.lz r-master.tar.xz r-master.tar.zst r-master.zip |
Diffstat (limited to 'šola/aps1/dn/autocomplete/rešitev.cpp')
-rw-r--r-- | šola/aps1/dn/autocomplete/rešitev.cpp | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/šola/aps1/dn/autocomplete/rešitev.cpp b/šola/aps1/dn/autocomplete/rešitev.cpp new file mode 100644 index 0000000..0a5f42c --- /dev/null +++ b/šola/aps1/dn/autocomplete/rešitev.cpp @@ -0,0 +1,143 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <stdbool.h> +struct beseda { + char * niz; + long pomem; +}; +static int compar_words (const void * aa, const void * bb) { + const char * a = ((const struct beseda *) aa)->niz; + const char * b = ((const struct beseda *) bb)->niz; + fprintf(stderr, "compar_words: %s, %s\n", a, b); + for (; *a && *b && *a == *b; a++, b++); + if (*a < *b) + return -1; + return *a > *b; +} +static int intlog(long n) { + int log = 1; + for (int dolžina = 1; dolžina < n; dolžina *= 2) + log++; + return log; +} +int main () { + long n; + if (scanf("%ld", &n) == EOF) { + perror("scanf n"); + return 1; + } + struct beseda * s = (struct beseda *) malloc(n*sizeof *s); + if (!s) { + perror("malloc s"); + return 1; + } + for (long i = 0; i < n; i++) { + if (scanf("%ms %ld", &(s[i].niz), &(s[i].pomem)) == EOF) { + perror("scanf"); + return 1; + } + } + qsort(s, n, sizeof *s, compar_words); + for (long i = 0; i < n; i++) { + fprintf(stderr, "s[%ld].niz = \"%s\"; s[%ld].pomem = %ld;\n", i, s[i].niz, i, s[i].pomem); + } + int log = intlog(n); + // fprintf(stderr, "log: %d\n", log); + long * max = (long *) malloc((n*log)*sizeof *max); + if (!max) { + perror("malloc max"); + return 1; + } + for (int i = 0; i < log; i++) { + for (long j = 0; j < n; j++) { + if (i == 0) { + max[i*n+j] = j; + continue; + } + if (j+(1 << (i-1)) >= n) { + max[i*n+j] = max[(i-1)*n+j]; + continue; + } + max[i*n+j] = s[max[(i-1)*n+j+(1 << (i-1))]].pomem > s[max[(i-1)*n+j]].pomem ? max[(i-1)*n+j+(1 << (i-1))] : max[(i-1)*n+j]; + } + } + long m; + if (scanf("%ld", &m) == EOF) { + perror("scanf m"); + return 1; + } + long * o = (long *) malloc(m*sizeof *o); + for (long i = 0; i < m; i++) { + char buf[20000]; + char bu2[20000]; + struct beseda prefix = { + .niz = buf, + .pomem = 0 + }; + struct beseda nextprefix = { + .niz = bu2, + .pomem = 0 + }; + if (scanf("%s", buf) == EOF) { + perror("scanf buf"); + return 1; + } + fprintf(stderr, "krneki: %s\n", buf); + strcpy(bu2, buf); + nextprefix.niz[strlen(nextprefix.niz)-1]++; + long l = 0, d = n; + while (l < d) { + long m = (l+d)/2; + switch (compar_words(&prefix, s+m)) { + case -1: + d = m-1; + break; + case 1: + l = m+1; + break; + case 0: + l = d = m; + break; + default: + assert(false); + } + } + long start = l; + fprintf(stderr, "found start = %ld;\n", start); + l = 0, d = n; + while (l < d) { + long m = (l+d)/2; + switch (compar_words(&nextprefix, s+m)) { + case -1: + d = m-1; + break; + case 1: + l = m+1; + break; + case 0: + l = d = m; + break; + default: + assert(false); + } + } + long end = l; + fprintf(stderr, "found end = %ld;\n", end); + int winsizelog = intlog(end-start)-1; + o[i] = 0; + if (winsizelog) + o[i] = s[max[winsizelog*n+(end-(1 << (winsizelog-1)))]].pomem > s[max[winsizelog*n+start]].pomem ? max[winsizelog*n+start] : max[winsizelog*n+(end-(1 << (winsizelog-1)))]; + fprintf(stderr, "o[%ld] = %ld;\n", i, o[i]); + } + bool devica = true; + for (long i = 0; i < m; i++) { + if (devica) + devica = false; + else + putchar(' '); + printf("%ld", o[i]); + } + putchar('\n'); +} |