You are on page 1of 16

PROGRAMIRANJE II

A06 – Pretraživanje

dr Dražen Brđanin (bdrazen@etfbl.net)


Goran Banjac (goran.banjac@etfbl.net)
Danijela Banjac (danijela.banjac@etfbl.net)
Aleksandar Keleč (aleksandar.kelec@etfbl.net)

2016.
A06 SEKVENCIJALNO PRETRAŽIVANJE
Napisati program u kojem treba u nizu cijelih brojeva pronaći broj koji se navodi kao prvi
argument komandne linije pomoću metode sekvencijalnog pretraživanja.
#include <stdio.h>
#include <stdlib.h>
int seq_search(int *niz, int n, int kljuc)
{ D:\>pretraga.exe -3
for (int i = 0; i < n; i++) Niz: 1 2 -3 4 5
if (niz[i] == kljuc) return i; Pronadjen element niza -3, na poziciji 2.
return -1; D:\>pretraga.exe 3
}
int main(int argc, char **argv)
Niz: 1 2 -3 4 5
{ Element 3 nije pronadjen u nizu.
int niz[] = { 1, 2, -3, 4, 5 }, i, n = sizeof(niz) / sizeof(int), kljuc;
if (argc < 2) return printf("Greska. Nema dovoljno argumenata."), 1;
kljuc = atoi(argv[1]);
printf("Niz:");
for (i = 0; i < n; i++)
printf(" %d", niz[i]);
i = seq_search(niz, n, kljuc);
if (i != -1)
printf("\nPronadjen element niza %d, na poziciji %d.", niz[i], i);
else
printf("\nElement %d nije pronadjen u nizu.", kljuc); return 0;
}
Pretraživanje 2
A06 SEKVENCIJALNO PRETRAŽIVANJE
Napisati program u kojem treba iz datoteke, čiji je naziv prvi argument komandne linije,
pročitati (binarno upisane) podatke o nepoznatom broju artikala i formirati odgovarajući
dinamički niz, a potom u formiranom nizu pronaći i ispisati artikal čiji se naziv unosi sa
standardnog ulaza. Atributi artikla su naziv, količina i cijena. Koristiti metodu
sekvencijalnog pretraživanja sa stražom.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct { char naziv[21]; double kol, cijena; } ARTIKAL;

int seq_search_straza(ARTIKAL *niz, char *kljuc)


{
int i = 0;
while (strcmp(niz[i].naziv, kljuc)) i++;
return i;
}

void pisi(ARTIKAL *art)


{
printf("%-20s %6.2lf %6.2lf %6.2lf", art->naziv, art->kol, art->cijena,
art->kol * art->cijena);
}

Pretraživanje 3
A06 SEKVENCIJALNO PRETRAŽIVANJE
int main(int argc, char *argv[]) {
int i, n = 0, c = 10, p;
ARTIKAL *niz, art; FILE *dat;
if (argc < 2) return printf("Nije naveden naziv datoteke."), 1;
niz = (ARTIKAL *)malloc(c * sizeof(ARTIKAL));
if (dat = fopen(argv[1], "rb")) {
do {
p = fread(&art, sizeof(ARTIKAL), 1, dat);
if (p) { D:\>artikli_pretraga.exe ARTIKLI.DAT
Unesite
if (n == c) niz = (ARTIKAL naziv artikla
*)realloc(niz, (c *= za
2) pretragu: Jabuke
* sizeof(ARTIKAL));
niz[n++] = art; } Rezultat pretrage:
} while (p); fclose(dat); === ==================== ====== ====== ======
} RB. NAZIV KOL. CIJENA UKUPNO
printf("Unesite naziv artikla===
za ====================
pretragu: "); scanf("%s", art.naziv);
====== ====== ======
if (n == c) niz = (ARTIKAL *)realloc(niz, (c += 1) * sizeof(ARTIKAL));
2. Jabuke 2.50 1.50 3.75
niz[n] = art; printf("Rezultat pretrage:\n");
=== ==================== ====== ====== ======
i = seq_search_straza(niz, art.naziv);
D:\>artikli_pretraga.exe
if (i == n) printf("Nije pronadjen artikal."); ARTIKLI.DAT
else { Unesite naziv artikla za pretragu: Maline
Rezultat
printf("=== ==================== pretrage:
====== ====== ======\n");
printf("RB. NAZIV KOL.
Nije pronadjenCIJENA UKUPNO\n");
artikal.
printf("=== ==================== ====== ====== ======\n");
printf("%2d. ", i + 1), pisi(niz + i);
printf("\n=== ==================== ====== ====== ======\n"); }
free(niz); return 0; }
Pretraživanje 4
A06 BINARNO PRETRAŽIVANJE
Napisati program u kojem treba iz datoteke, čiji je naziv prvi argument komandne linije,
pročitati podatke o nepoznatom broju studenata koji su sortirani po broju indeksa, i
formirati odgovarajući dinamički niz, a potom u formiranom nizu pronaći i ispisati podatke
o studentu čiji se broj indeksa unosi sa standardnog ulaza. Podaci koji se vode o studentu
su: indeks, ime, prezime i prosjek.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{ char indeks[8], ime[21], prezime[21]; double prosjek; } STUDENT;
int ucitaj(FILE *in, STUDENT *s){
return fscanf(in, "%*d. %s %s %s %lf", s->indeks, s->prezime, s->ime, &s->prosjek);
}
int bin_search(STUDENT *niz, int n, char *kljuc){
int begin = 0, end = n - 1, sredina;
do {
sredina = (begin + end) / 2;
if (!strcmp(niz[sredina].indeks, kljuc)) return sredina;
if (strcmp(niz[sredina].indeks, kljuc) > 0)
end = sredina - 1;
else
begin = sredina + 1;
} while (begin <= end); return -1;
}

Pretraživanje 5
A06 BINARNO PRETRAŽIVANJE
int main(int argc, char *argv[]){
int i, p, n = 0, c = 10; char s[100], kljuc[20]; FILE *in;
if (argc < 2) return printf("Greska."), 1;
STUDENT st, *niz = (STUDENT *)malloc(c * sizeof(STUDENT));
if (in = fopen(argv[1], "r")) {
fgets(s, 100, in); fgets(s, 100, in); fgets(s, 100, in);
do {
if ((p = ucitaj(in, &st)) == 4) {
if (n == c) niz = (STUDENT *)realloc(niz, (c *= 2) * sizeof(STUDENT));
niz[n++] = st; }
} while (p); fclose(in);
D:\>studenti_pretraga.exe STUDENTI.TXT
}
printf("UnesiteUnesite broj indeksa
broj indeksa za pretragu:
za pretragu: 1104/14
"); scanf("%s", kljuc);
Rezultat pretrage:
printf("Rezultat pretrage:\n"); i = bin_search(niz, n, kljuc);
if (i == -1) === ======= ==================== ==================== =======
printf("NijeRB. INDEKSstudent.");
pronadjen PREZIME IME PROSJEK
else { === ======= ==================== ==================== =======
printf("=== ======= ====================
3. 1104/14 Nikolic ====================
Nikolina =======\n"); 9.81
printf("RB. INDEKS PREZIME IME PROSJEK\n");
=== ======= ==================== ==================== =======
printf("=== ======= ==================== ==================== =======\n");
printf("%2d.D:\>studenti_pretraga.exe
%s %-20s %-20s %7.2lf\n", i +STUDENTI.TXT
1, niz[i].indeks, niz[i].prezime,
Unesite broj indeksa
niz[i].ime, niz[i].prosjek); za pretragu: 1103/14
printf("=== Rezultat pretrage:
======= ==================== ==================== =======\n");
Nije pronadjen
} free(niz); return 0; student.
}
Pretraživanje 6
A06 INTERPOLACIONO PRETRAŽIVANJE
Napisati program koji simulira pretragu rječnika. Potrebno je učitati riječi iz datoteke
rjecnik.txt i kreirati odgovarajući dinamički niz, a potom u formiranom nizu pronaći i
ispisati riječ koja se unosi sa standardnog ulaza. Zadatak riješiti kombinovanjem
interpolacionog i sekvencijalnog pretraživanja (prvo interpolacionim pretraživanjem
locirati neku riječ koja počinje istim slovom, a zatim sekvencijalnim pretraživanjem pronaći
željenu riječ, ako postoji).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int inter_search(char **niz, int n, char kljuc) {
int begin = 0, end = n - 1, sredina, brojilac, imenilac;
do {
brojilac = (kljuc - niz[begin][0]) * (end - begin);
imenilac = niz[end][0] - niz[begin][0];
if (imenilac == 0) return niz[begin][0] == kljuc ? begin : -1;
sredina = begin + brojilac / imenilac;
if (sredina < begin || sredina > end) return -1;
else if (niz[sredina][0] == kljuc) return sredina;
if (kljuc < niz[sredina][0]) end = sredina - 1;
else begin = sredina + 1;
} while (begin <= end);
return -1;
}
Pretraživanje 7
A06 INTERPOLACIONO PRETRAŽIVANJE
int main(int argc, char *argv[]) {
int i, j, n = 0, c = 20, p = 0; FILE *dat; char **rjecnik, rijec[21];
rjecnik = (char **)malloc(c * sizeof(char *));
if (dat = fopen("rjecnik.txt", "r")) {
while (fscanf(dat, "%s\n", rijec) != EOF) {
if (n == c) rjecnik = (char **)realloc(rjecnik, (c *= 2) * sizeof(char *));
rjecnik[n] = (char *)malloc((strlen(rijec) + 1) * sizeof(char));
D:\>rjecnik.exe
strcpy(rjecnik[n++], rijec);
} Unesite rijec za pretragu: krug
fclose(dat);
Rezultat pretrage:
} Rijec krug postoji u rjecniku.
printf("Unesite rijec za pretragu: "); scanf("%s", rijec);
D:\>rjecnik.exe
printf("Rezultat pretrage:\n");
Unesite rijec za pretragu:
i = j = inter_search(rjecnik, jabuke
n, rijec[0]);
Rezultat
while (i >= pretrage: == rijec[0]) && !p)
0 && (rjecnik[i][0]
Rijec jabuke ne rijec))
if (!strcmp(rjecnik[i--], postoji u rjecniku.
p = 1;
while (++j < n && (rjecnik[j][0] == rijec[0]) && !p)
if (!strcmp(rjecnik[j], rijec))
p = 1;
printf("Rijec %s%s postoji u rjecniku.", rijec, p ? "" : " ne");
for (i = 0; i < n; i++) free(rjecnik[i]);
free(rjecnik); return 0;
}

Pretraživanje 8
A06 BINARNO PRETRAŽIVANJE
Program koji pogađa nenegativan broj koji je korisnik zamislio.
#include <stdio.h> 11
int main()
{
int begin = 0, end = 1, sredina, odg;
printf("Zamislite prirodan broj!\n");
while (1)
{
printf("Da li je broj veci od %d? (1/0) ", end);
scanf("%d", &odg);
if (!odg) break;
begin = end + 1; end *= 2; Zamislite prirodan broj!
} Da li je broj veci od 1? (1/0) 1
while (begin < end) Da li je broj veci od 2? (1/0) 1
{
Da li je broj veci od 4? (1/0) 1
sredina = (begin + end) / 2;
Da li je broj veci od 8? (1/0) 1
printf("Da li je broj veci od %d? (1/0) ", sredina);
scanf("%d", &odg); Da li je broj veci od 16? (1/0) 0
if (odg) begin = sredina + 1; Da li je broj veci od 12? (1/0) 0
else end = sredina; Da li je broj veci od 10? (1/0) 1
} Da li je broj veci od 11? (1/0) 0
printf("Zamislili ste broj: %d", end); Zamislili ste broj: 11
return 0;
}
Pretraživanje 9
A06 BINARNO PRETRAŽIVANJE
Program koji određuje realnu nulu jednačine sa odgovarajućom preciznošću,
kombinacijom eksponencijalnog i binarnog pretraživanja.
#include <stdio.h>
#include <math.h>
double rjesenje(double(*f)(double), double eps)
{
double begin = 0, end = 0.1, sredina;
while ((*f)(begin) * (*f)(end) >= 0)
end = (begin = end) * 2;
while (end - begin > eps) {
sredina = (begin + end) / 2.0;
if ((*f)(begin) * (*f)(sredina) > 0)
begin = sredina;
else
end = sredina; cos(1.56875)=0.00205
}
return sredina;
}
int main()
{
double x = rjesenje(cos, 0.01);
printf("cos(%.5f)=%.5f\n", x, cos(x));
return 0;
}

Pretraživanje 10
A06 SPOLJAŠNJE PRETRAŽIVANJE
Napisati program u kojem treba sa standardnog ulaza učitati podatke za n studenata, a
potom podatake o studentima upisati u datoteku čiji je naziv prvi argument komandne
linije. Atributi studenta su indeks, prezime, ime i prosjek. Pored toga, potrebno je kreirati i
strukturu INDEKS, koja predstavlja look-up tabelu, pomoću koje će se efikasnije
pretraživati datoteka sa studentima. Atributi indeksa su kljuc i adresa. Indekse je potrebno
održavati sortirane u dinamičkom nizu a zatim sačuvati u datoteku čiji je naziv drugi
argument komandne linije.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct { char indeks[8], ime[21], prezime[21]; double prosjek; } STUDENT;


typedef struct { char kljuc[8]; int adresa; } INDEKS;

void citaj_studenta(STUDENT *st) {


printf(" Indeks: "); scanf("%s", st->indeks);
printf(" Prezime: "); scanf("%s", st->prezime);
printf(" Ime: "); scanf("%s", st->ime);
printf(" Prosjek: "); scanf("%lf", &st->prosjek);
}
void pisi_footer_u_fajl(FILE *dat)
{ fprintf(dat, "=== ======= ==================== ==================== =======\n"); }

Pretraživanje 11
A06 SPOLJAŠNJE PRETRAŽIVANJE
void pisi_header_u_fajl(FILE *dat) {
fprintf(dat, "=== ======= ==================== ==================== =======\n");
fprintf(dat, "RB. INDEKS PREZIME IME PROSJEK\n");
fprintf(dat, "=== ======= ==================== ==================== =======\n");
}
void upisi_studenta_u_fajl(STUDENT st, FILE *dat, INDEKS *indeksi, int rb) {
INDEKS ind;
strcpy(ind.kljuc, st.indeks);
ind.adresa = ftell(dat);
azuriraj_indekse(indeksi, ind, rb);
fprintf(dat, "%2d. ", rb);
fprintf(dat, "%-7s %-20s %-20s %7.2lf\n", st.indeks, st.prezime, st.ime, st.prosjek);
}
void upisi_indekse_u_fajl(INDEKS *niz, int n, FILE *dat) {
int i;
for (i = 0; i < n; i++) {
fprintf(dat, "%s %d\n", niz[i].kljuc, niz[i].adresa); }
}
void azuriraj_indekse(INDEKS *niz, INDEKS ind, int n) {
int i;
for (i = n - 1; i > 0 && strcmp(ind.kljuc, niz[i - 1].kljuc) < 0; i--)
niz[i] = niz[i - 1];
niz[i] = ind;
}

Pretraživanje 12
A06 SPOLJAŠNJE PRETRAŽIVANJE
int main(int argc, char *argv[]) {
int i, n;
FILE *dat;
STUDENT st;
INDEKS *indeksi;
if (argc < 3) return printf("Nisu navedeni svi argumenti."), 1;
do printf("n="), scanf("%d", &n); while (n < 1);
indeksi = (INDEKS *)malloc(n * sizeof(INDEKS));
if (dat = fopen(argv[1], "w")) {
pisi_header_u_fajl(dat);
D:\>studenti_unos.exe studenti.txt indeksi.txt
for (i = 1; i <= n; i++)
n=4
{
printf("Podaci o %d. Podaci o 1. studentu:
studentu:\n", i), citaj_studenta(&st);
Indeks: 1101/14
upisi_studenta_u_fajl(st, dat, indeksi, i);
} Prezime: Markovic
pisi_footer_u_fajl(dat); Ime: Marko
fclose(dat);
} Prosjek: 8.75
if (dat = fopen(argv[2], "w")). {. .
upisi_indekse_u_fajl(indeksi, n, dat);
Podaci o 4. studentu:
fclose(dat);
} Indeks: 1102/14
free(indeksi); Prezime: Aleksic
return 0; Ime: Aleksandra
} Prosjek: 8.8

Pretraživanje 13
A06 SPOLJAŠNJE PRETRAŽIVANJE
Napisati program u kojem treba u datoteci studenti.txt, iz prethodnog zadatka, pronaći
podatke o studentu čiji se broj indeksa unosi sa standardnog ulaza. Potrebno je iz datoteke
indeksi.txt pročitati sve indeksne zapise i formirati dinamički niz, u kojem će se na osnovu
unesenog broja indeksa (kljuc), pronaći odgovarajuća adresa početka zapisa o studentu u
datoteci studenti.txt, te na taj način pročitati i ispisati podatke o pronađenom studentu.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct { char indeks[8], ime[21], prezime[21]; double prosjek; } STUDENT;
typedef struct { char kljuc[8]; int adresa; } INDEKS;

int bin_search(INDEKS *niz, int n, char *kljuc) {


int begin = 0, end = n - 1, sredina;
do {
sredina = (begin + end) / 2;
if (!strcmp(niz[sredina].kljuc, kljuc)) return sredina;
if (strcmp(niz[sredina].kljuc, kljuc) > 0)
end = sredina - 1;
else
begin = sredina + 1;
} while (begin <= end);
return -1;
}

Pretraživanje 14
A06 SPOLJAŠNJE PRETRAŽIVANJE
int main(int argc, char *argv[]) {
int i, n = 0, c = 10; FILE *dat; STUDENT st; INDEKS ind, *indeksi;
indeksi = (INDEKS *)malloc(c * sizeof(INDEKS));
if (dat = fopen("indeksi.txt", "r")) {
while (fscanf(dat, "%s %d\n", ind.kljuc, &ind.adresa) != EOF) {
if (n == c) indeksi = (INDEKS *)realloc(indeksi, (c *= 2) * sizeof(INDEKS));
indeksi[n++] = ind; }
fclose(dat); }
printf("Unesite broj indeksa za pretragu: "); scanf("%s", st.indeks);
printf("Rezultat pretrage:\n"); i = bin_search(indeksi, n, st.indeks);
if (i == -1) printf("Nije pronadjen student.");
D:\>studenti_pretraga.exe
else {
Unesite broj indeksa za pretragu: 1102/14
if (dat = fopen("studenti.txt", "r")) {
Rezultat
fseek(dat, pretrage: SEEK_SET); // pozicioniranje na pocetak zapisa
indeksi[i].adresa,
=== =======
if (fscanf(dat, "%d. ==================== ====================
%s %s %s %lf\n", &i, st.indeks, =======
st.prezime, st.ime,
RB. INDEKS
&st.prosjek) == 5) PREZIME
{ IME PROSJEK
printf("=== ===========================
=== ======= ==================== ==================== =======\n");
==================== =======
printf("RB. INDEKS Aleksic
4. 1102/14 PREZIME IME
Aleksandra PROSJEK\n");
8.80
printf("=== ======= ==================== ==================== =======\n");
=== ======= ==================== ==================== =======
printf("%2d. %-7s %-20s %-20s %7.2lf\n", i, st.indeks, st.prezime, st.ime,
D:\>studenti_pretraga.exe
st.prosjek);
Unesite
printf("=== broj ====================
======= indeksa za pretragu: 1105/14
==================== =======\n");
Rezultat
} fclose(dat); pretrage:
Nije pronadjen
}} free(indeksi); return 0;student.
}
Pretraživanje 15
A06 ZADACI ZA VJEŽBU
1. Napisati program za pogađanje cijelih brojeva u kojem treba iz tekstualne datoteke,
čiji je naziv prvi argument komandne linije, pročitati sortirano upisane cijele brojeve,
iz intervala [0, 20], a potom iz pet pokušaja pokušati pogoditi što više brojeva, i
ispisati na standardni izlaz broj uspješnih pogodaka. Za pretragu koristiti rekurzivno
binarno pretraživanje.
2. Napisati program koji simulira pretragu telefonskog imenika. Potrebno je učitati
osobe iz datoteke imenik.txt i kreirati odgovarajući dinamički niz, a potom u
formiranom nizu pronaći i ispisati osobu čije se prezime i ime unosi sa standardnog
ulaza. Koristiti interpolaciono pretraživanje.
3. Napisati program u kojem treba iz datoteke, čiji je naziv prvi argument komandne
linije, pročitati (binarno upisane) podatke o nepoznatom broju osoba i formirati
odgovarajući dinamički niz, a potom u formiranom nizu pronaći i ispisati osobu čiji se
JMBG unosi sa standardnog ulaza. Atributi osobe su JMBG, ime, prezime i rodjen.
4. Napisati program kojim se porede brzine izvršavanja različitih algoritama
pretraživanja na istom nizu pseudoslučajnih vrijednosti.

Pretraživanje 16

You might also like