summaryrefslogtreecommitdiffstats
path: root/inf/rtk/2021-šolsko-delo/dos/5.c
blob: 6c5d0d9f9e60ab580caac99a47363c687e420d27 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct niz {
	int d; /* dolzina niza */
	char * n; /* niz */
};

/* funkcija odvrne 0, ce sta niza enako dolga, -1, ce je prvi krajsi od drugega in 1, ce je prvi daljsi od drugega */
int primerjaj_niza (const void * a, const void * b) {
	const struct niz * sna = (const struct niz *) a; /* Cjeva carovnija vlivanja */
	const struct niz * snb = (const struct niz *) b;
	return (sna->d > snb->d) - (sna->d < snb->d); /* preprosto primerjanje dveh stevilk */
}

struct niz * podprogram (
		struct niz * n, /* seznam nizov */
		int nizov, /* stevilo nizov */
		struct niz * p /* prejsnji niz za rekurzijo */
		) {
	int i = 0; /* iteracijski decek */
	int j = 0; /* iteracijski decek, ki je potopljen v 1. globino vgnezdene zanke */
	int o = 0; /* oddaljenost prvega niza, ki ima vecjo dolzino */
	int s = 0; /* ali smo ze en znak izpustili */
	int a = 1; /* niz je aplikatibilen */
	struct niz * od = p; /* kazalec na odgovor, nastavljen na prejsnji niz, ce nizi te velikosti niso vec aplikatibilni */
	struct niz * op; /* kazalec na prihodnji morebitni odgovor, seveda zgolj, ce je daljsi */
	int zadnja_runda = 0; /* samoumevno */
	for (o = 0; n[o].d == n[0].d; o++) /* za vsak niz najkrajse dolzine */
		if (o+1 >= nizov) { /* ce smo pri koncu seznama nizov */
			zadnja_runda = 1; /* pri koncu seznama nizov smo, to si zabelezimo */
			o++; /* ker se pri break tretji stavek for zanke ne izvede na koncu */
			break;
		}
	for (i = 0; i < o; i++) { /* podobno kot prejsnja zanka, le da jnam je sedaj o znan */
		s = 0; /* ponastavimo */
		a = 1; /* ponastavimo */
		for (j = 0; j < p->d; j++) { /* za vsak znak prejsnjega niza */
			if (p->n[j] != n[i].n[j+s]) /* ce se nas niz za en znak vec ne ujema s prejsnjim */
				s++;
			if (s > 1) { /* ce se je prejsen ce stavek ze zgodil, smo izpustili ze dva znaka, kar ni dovoljeno */
				a = 0; /* ta niz ni aplikatibilen */
				break;
			}
		}
		if (a && zadnja_runda) /* ce smo pri koncu in smo nasli aplikatibien niz - super, vrnemo ga skozi rekurzicno verigo, to je niz, ki ga iscemo (;:! */
			return &n[i]; /* ja, spet bi lahko uporabil n+i ampak se mi tole zdi lepše */
		if (a) {
			op = podprogram(n+o, nizov-o, &n[i]); /* poklicemo podprogram z mnozico nizov zgolj vecjih velikosti, kot ta velikost - zato potrebujemo o (: */
			if (op != NULL && op->d > od->d) /* ce je odgovor boljsi od do sedaj znanega */
				od = op; /* kazalec na starega prepisemo */
		}
	}
	return od;
}

/* argv+1 je seznam nizov.
 * */
#if __INCLUDE_LEVEL__ == 0
int main (int argc, char ** argv) {
	if (argc < 1+1) {
		fprintf(stderr, "uporaba: %s splatters splatter platter latter later late ate at a (nenujno po velikosti)\n", argv[0]);
		return 1;
	}
	struct niz * n = malloc(sizeof(struct niz)*argc); /* prostor za nize */
	size_t i = 0; /* iteracijski decek */
	struct niz * o; /* odgovor */
	struct niz p = { /* virtualen prejsnji niz, ki ga damo v rekurzicno funkcijo */
		.d = 0,
		.n = "",
	}; /* zato, da ni treba delati dodatnega preizkusa, ce je funkcija podprogram pognana iz funkcije podprogram ali iz uporabnkove funkcije, recimo main */
	for (i = 0; i < argc-1; i++) { /* pridobimo velikosti nizov */
		n[i].d = strlen(argv[1+i]); /* predpomnimo dolzino niza */
		n[i].n = argv[i+1]; /* zapisemo kazalec do konstantnega niza iz argv */
	}
	/* sedaj pa nize razvrstimo po velikosti s funkcijo iz STANDARDNE KNJIZNICE qsort */
	qsort(n, argc-1, sizeof(struct niz), primerjaj_niza);
	/* sedaj pa lahko zacnemo z nasim skriptom */
	o = podprogram(n, argc-1, &p);
	fprintf(stdout, "%s\n", o->n);
	free(n);
	n = NULL;
	return 0;
}
#endif