94
Osnove programiranja 2 Interdisciplinarni študij Računalništvo in matematika Viljan Mahnič UNIVERZA V LJUBLJANI Fakulteta za računalništvo in informatiko

Interdisciplinarni študij Računalništvo in matematika

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2Interdisciplinarni študij Računalništvo in matematika

Viljan Mahnič

UNIVERZA V LJUBLJANIFakulteta za računalništvo in informatiko

Page 2: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 2 - ©Viljan Mahnič

Organizacija programa in dostopnost deklaracij

• Območje veljavnosti deklaracij spremenljivk– lokalne in globalne spremenljivke

• Dostopno določilo static– spremenljivke objekta in spremenljivke razreda– metode objekta in metode razreda– referenca this v metodah objekta

• Dostopno določilo final

• Dostopna določila public, private in protected

• Uporaba vnaprej deklariranih razredov– Math– Character

Page 3: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 3 - ©Viljan Mahnič

Območje veljavnosti deklaracij spremenljivk

• Deklaracija spremenljivke velja– od mesta, kjer je bila spremenljivka deklarirana– do konca bloka, v katerem smo jo deklarirali

• Primer: gnezdenje blokov{ // zunanji blok

int spr1=10;...{ // notranji blok

int spr2=20;... // obstajata spr1 in spr2int spr1=34; // napaka

}// spr1 še vedno obstaja, spr2 pa ne...

}

Page 4: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 4 - ©Viljan Mahnič

Lokalne in globalne spremenljivke

• Globalne spremenljivke– deklarirane so na ravni razreda– dostopne so vsem metodam v razredu

• Lokalne spremenljivke– deklarirane so znotraj posameznih metod– dostopne so samo v metodi, kjer so deklarirane

• Globalne spremenljivke so lahko statične ali vezane na posamezne objekte, odvisno od dostopnega določila static– statične spremenljivke: obstaja ena sama spremenljivka za celoten

razred, zato jim rečemo tudi spremenljivke razreda (ang. class variables)

– spremenljivke objekta: vsakemu objektu pripada svoja spremenljivka, ki vsebuje vrednost atributa tistega objekta (ang. instance variables)

Page 5: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 5 - ©Viljan Mahnič

Lokalne in globalne spremenljivke

• Primer: Razred, ki opisuje zgradbo objektovpublic class Primer1{private double atr1; // vsak objekt ima 2 atributa, ki sta globalniprivate int atr2; // spremenljivki, dostopni v celem razredupublic void metoda1(){int spr3=1; // lokalni spremenljivki,int spr4=25; // dostopni v metodi metoda1()// obstajajo atr1, atr2, spr3 in spr4

}public int metoda2(){

double spr5=500.0; // lokalna spremenljivka// obstajajo atr1, atr2=10 in spr5

}}

Page 6: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 6 - ©Viljan Mahnič

Lokalne in globalne spremenljivke

• Primer: Razred, ki predstavlja aplikacijopublic class Primer2{static double spr1=2.5; // globalni spremenljivki,static int spr2=10; // dostopni v celem razredupublic static void main(String[] args){int spr3=1; // lokalni spremenljivki,int spr2=25; // dostopni v metodi main()// obstajajo spr1=2.5, spr2=25 in spr3=1

}public static void xy(){

double spr4=500.0; // lokalna spremenljivka// obstajajo spr1=2.5, spr2=10 in spr4=500.0

}}

Page 7: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 7 - ©Viljan Mahnič

Statične spremenljivke in spremenljivke objekta

• Statične spremenljivke (ang. class variables)– tipične so za razrede, ki predstavljajo aplikacije, vendar lahko nastopajo

tudi v razredih, ki opisujejo zgradbo objektov– deklarirane so z rezervirano besedo static– obstaja samo ena kopija spremenljivke– to kopijo uporabljajo vse metode in vsi objekti– spremenljivka obstaja tudi v primeru, ko nismo kreirali nobenega objekta– sprememba vrednosti je dostopna vsem objektom in metodam v razredu

• Spremenljivke objekta (ang. instance variables)– nastopajo v razredih, ki opisujejo zgradbo objektov– pri deklaraciji ne smemo uporabiti dostopnega določila static– vsak objekt ima svojo kopijo spremenljivke (tj. svojo vrednost atributa)– sprememba vrednosti se odraža samo znotraj objekta

Page 8: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 8 - ©Viljan Mahnič

Statične metode in metode objekta

• Dostopno določilo static pri metodah– statične metode ali metode razreda (ang. class methods)– metode objekta (ang. instance methods)

• Statične metode – tipične so za razrede, ki predstavljajo aplikacije, in razrede, ki služijo

kot knjižnice podprogramov (npr. razred Math)– deklariramo jih z dostopnim določilom static– v pomnilniku so shranjene samo enkrat – niso vezane na posamezne objekte, ampak so skupne za celoten razred– uporabljamo jih tudi takrat, ko ne obstaja noben objekt– ne morejo posegati v atribute posameznih objektov– metoda main() mora biti obvezno statična– če deklariramo statično metodo v razredu, ki je namenjen generiranju

objektov, potem je ta skupna (tj. enaka) za vse objekte

Page 9: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 9 - ©Viljan Mahnič

Metode razreda in metode objekta

• Metode objekta– vezane so na posamezne objekte (tj. primerke nekega razreda)

• predstavljamo si lahko, da ima vsak objekt svoje metode• v resnici so tudi metode, ki pripadajo objektom istega tipa, shranjene

v pomnilniku samo enkrat; s posebnim mehanizmom dosežemo, da se izvede prava metoda (dinamično povezovanje)

– tipične so za razrede, ki so namenjeni generiranju objektov– omogočajo dostop do posameznih atributov v objektu– pri njihovi deklaraciji ne smemo uporabiti dostopnega določila static

– ob klicu metode objekta je treba obvezno navesti tudi ime objekta, ki mu metoda pripada

<ime objekta> . <ime metode> (<dejanski parametri>)<ime razreda> . <ime objekta> . <ime metode> (<dejanski parametri>)

Page 10: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 10 - ©Viljan Mahnič

Referenca this• Implicitno prisotna v vsaki metodi objekta

– predstavlja naslov objekta, na katerega se nanaša klic metode– ta naslov omogoča, da dostopamo do spremenljivk pravega objekta– pred vsakim sklicevanjem na spremenljivko objekta dejansko stoji

referenca this– referenco this avtomatsko vstavi prevajalnik, lahko pa jo vključi že

programer

public void izpisiVse(){System.out.println("Maticna stevilka: "+this.matStev);System.out.println("Priimek in ime: "+this.priimek+''+this.ime);

System.out.println("Stevilo ur: "+this.stUr);}

Page 11: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 11 - ©Viljan Mahnič

Določilo final• Kadar želimo preprečiti spremembo neke deklaracije

– pri spremenljivkah: vrednost spremenljivke se ne more več spremeniti– pri metodah: metode ni moč redefinirati (je dokončna)– pri razredih: razreda ni moč razširiti (vse metode so dokončne)

• Deklaracije konstant– konstante deklariramo na enak način kot spremenljivke, le da dodamo

rezervirano besedo final– velja dogovor, da imena konstant pišemo z velikimi črkami– static final double PI=3.14159;– konstanti moramo prirediti vrednost ob deklaraciji; kasneje to ni več

mogoče– prednost uporabe konstant

• boljša čitljivost programa• enostavnejše vzdrževanje

Page 12: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 12 - ©Viljan Mahnič

Dostopna določila public, private in protected

• Določajo način dostopa do posameznih atributov in metod v razredu

iz kateregakoli razreda v istem paketu in iz kateregakoli podrazreda ne glede na paket

protected

samo znotraj razredaprivate

iz kateregakoli razreda ne glede na paket

public

iz kateregakoli razreda v istem paketu

brez dostopnega določila

Dovoljen dostopDostopno določilo

Page 13: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 13 - ©Viljan Mahnič

Vnaprej deklarirani razredi

• V Javi obstaja približno 500 vnaprej deklariranih razredov– ti razredi so shranjeni v obliki paketov– paket si lahko predstavljamo kot skupino sorodnih razredov, ki so

shranjeni v isti mapi (poddirektoriju)– paket java.lang vsebuje osnovne razrede, ki se največ uporabljajo

• Uporaba vnaprej deklariranih razredov– nekateri paketi, kot npr. java.lang, so na razpolago avtomatsko – uporabo ostalih paketov ali razredov je treba napovedati s stavkom import, ki mora biti naveden na začetku programa• import java.util.* napove uporabo vseh razredov iz paketa java.util

• import java.util.Date napove uporabo razreda Date iz paketa java.util

Page 14: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 14 - ©Viljan Mahnič

Razred Math• Vsebuje matematične konstante in metode

– deklariran je v paketu java.lang– klicanje konstant (PI, E): Math.<ime konstante>– klicanje metod: Math.<ime metode>(<argumenti>)

eksponentna in logaritemska funkcijaexp(x),log(x)

naključno število med 0.0 in 1.0random()

kvadratni koren iz xsqrt(x)

zaokroževanje na najbližje celo številoround(x)

obratne trigonometrične funkcijeasin(x),acos(x),atan(x)

trigonometrične funkcije sinus, kosinus, tangenssin(x),cos(x),

tan(x)

absolutna vrednost xabs(x)

Page 15: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 15 - ©Viljan Mahnič

Razred Character• Vsebuje koristne metode za delo z znaki

– deklariran je v paketu java.lang– klicanje metod: Character.<ime metode>(<argChar>)

Preveri, ali je znak presledek, tab, newline, carriage return ali form feed

isWhiteSpace()

Preveri, ali je znak črka ali številkaisLetterOrDigit()

Preveri, ali je znak črkaisLetter()

Preveri, ali je znak številka ('0' – '9')isDigit()

Pretvori veliko črko v malotoLowerCase()

Preveri, ali je znak mala črkaisLowerCase()

Pretvori malo črko v velikotoUpperCase()

Preveri, ali je znak velika črkaisUpperCase()

Page 16: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 16 - ©Viljan Mahnič

Urejanje

• Seznanitev z nekaterimi algoritmi

• Maksimalno izkoriščanje konceptov objektno usmerjenega programiranja– rešitev, ki jo bomo sprogramirali, bo omogočala urejanje objektov

kateregakoli tipa

• Ocenjevanje časovne zahtevnosti posameznih algoritmov– ocenimo število tipičnih operacij (primerjanje, premik)– preprosti algoritmi zahtevajo čas velikostnega reda n2

– izpopolnjeni algoritmi zahtevajo čas velikostnega reda n·log2n

Page 17: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 17 - ©Viljan Mahnič

Urejanje

• Algoritmi– urejanje z navadnim izbiranjem (že poznamo)– urejanje z navadnim vstavljanjem– urejanje s porazdelitvami (Quicksort)

• Uporaba konceptov objektno usmerjenega programiranja omogoča, da sprogramiramo rešitev, ki je uporabna za vse vrste podatkov– urejamo tabelo, ki vsebuje podatke tipa Element– Element je abstraktni razred, ki vsebuje samo metodo manjsi– to zadostuje, da sprogramiramo katerikoli algoritem za urejanje– dejanske podatke, ki jih želimo urediti, deklariramo kot razširitev

razreda Element

Page 18: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 18 - ©Viljan Mahnič

Urejanje

• Deklaracija razred Elementpublic abstract class Element{public abstract boolean manjsi (Element b)

}

• Primer razširitve, ko želimo urediti podatke o študentihpublic class Student extends Element{String priimek, ime;double povpOcena;

Student(String p,String i,double po){priimek=p;ime=i;povpOcena=po;

}

Page 19: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 19 - ©Viljan Mahnič

Urejanje

• Primer razširitve (nadalj.)

public boolean manjsi(Element b){// konverzija iz abstraktnega tipa v tip StudentStudent s=(Student) b; // primerjava povprečnih ocen return this.povpOcena<s.povpOcena;

}

public String toString(){return priimek+" "+ime+" "+povpOcena;

}}

Page 20: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 20 - ©Viljan Mahnič

Urejanje z navadnim vstavljanjem

• Grob opis algoritmafor (i=1; i<a.length; ++i) //za vse elemente od drugega do

zadnjega{x=a[i];vstavi x na pravo mesto, upoštevajoč elemente a[0] do a[i];

}

• Prikaz delovanja na konkretnem primeru (za cela števila)i=1 44 55 12 42 94 18 6 67i=2 44 55 12 42 94 18 6 67i=3 12 44 55 42 94 18 6 67i=4 12 42 44 55 94 18 6 67i=5 12 42 44 55 94 18 6 67i=6 12 18 42 44 55 94 6 67i=7 6 12 18 42 44 55 94 67

6 12 18 42 44 55 67 94

Page 21: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 21 - ©Viljan Mahnič

Urejanje z navadnim vstavljanjem

• Formulacija v obliki podprogramapublic static void straightinsertion(Element[] a){

int i,j;Element x;for (i=1; i<a.length; ++i){x=a[i];j=i-1;while (j>=0 && x.manjsi(a[j])){a[j+1]=a[j];--j;

} a[j+1]=x;

} }

Page 22: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 22 - ©Viljan Mahnič

Urejanje z navadnim vstavljanjem

• Sestavni deli rešitve– razred Element: abstraktna metoda manjsi– razred SortiranjeObjektov: knjižnica metod za urejanje– razred Student: tip podatkov, ki jih bomo urejali, redefinicija

metode manjsi– razred GlavniProgram: naša aplikacija

• Razred GlavniProgrampublic class GlavniProgram{public static void main(String[] args){ Student[] s=new Student[10];pripraviPodatke(s);izpisiPodatke(s); // pred urejanjemSortiranjeObjektov.straightinsertion(s);izpisiPodatke(s); // po urejanju

}

Page 23: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 23 - ©Viljan Mahnič

Urejanje z navadnim vstavljanjem

• Razred GlavniProgram (nadalj.)static void pripraviPodatke(Student[] s){ s[0]=new Student("Novak","Janez",8.12);s[1]=new Student("Petelin","Marko",7.72);s[2]=new Student("Kranjec","Ludvik",9.04);s[3]=new Student("Lenko","Friderik",6.74);s[4]=new Student("Pametnjakovic","Zdravko",8.04);...s[9]=new Student("Kopac","Ivan",6.89);

}

static void izpisiPodatke(Student[] s){for (int i=0; i<s.length; ++i)System.out.println(s[i].toString());

System.out.println();}

}

Page 24: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 24 - ©Viljan Mahnič

Urejanje z navadnim vstavljanjem

• Analiza učinkovitosti– število primerjanj– število pomikov

• Število primerjanj– najprej določimo število primerjanj v i-tem koraku– nato izračunamo vsoto po vseh korakih

– zaključna ugotovitev: C = o(n2)

2i

C

iC

1C

i

i

i

ave

max

min

=

=

=

41)n(n1)n...32(1

21

2i

21)n(n1n...321i

1n

1n

1iave

1n

1imax

min

C

CC

−=−++++==

−=−++++==

−=

∑−

=

=

Page 25: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 25 - ©Viljan Mahnič

Urejanje z navadnim vstavljanjem

• Število premikov– v i-tem koraku: število premikov je za 1 večje od števila

primerjanj

– v celoti: izračunamo vsoto po vseh korakih

• Obe oceni pokažeta, da čas narašča s kvadratom števila elementov: T=o(n2)

4)3nn(411)(n

41)n(n

1)(n1)n...32(1211)

2i(

2

1n

1iaveM

−+=−+−

=

=−+−++++=+= ∑−

=

1CM ii aveave+=

Page 26: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 26 - ©Viljan Mahnič

Urejanje s porazdelitvami - Quicksort

• Osnova je porazdelitveni algoritem, ki tabelo razdeli na 2 dela1. naj bo x poljubni element tabele (npr. element na sredini)2. pregledujemo tabelo z leve, dokler ne naletimo na element ai, ki je večji ali

enak x3. pregledujemo tabelo z desne, dokler ne naletimo na element aj, ki je manjši ali

enak x4. zamenjamo ai in aj5. ponavljamo korake 2, 3 in 4, dokler se obe pregledovanji ne srečata sredi tabele

• Primer: 44 55 12 42 94 6 18 67i j

18 55 12 42 94 6 44 67i j

18 6 12 42 94 55 44 67i j

18 6 12 42 94 55 44 67j i

Page 27: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 27 - ©Viljan Mahnič

Urejanje s porazdelitvami - Quicksort

• Zapis porazdelitvenega algoritma v Javiint i=0, j=a.length-1;Element x=a[(i+j)/2], w;do{ while (a[i].manjsi(x)) ++i;while (x.manjsi(a[j])) --j;if (i<=j){w=a[i]; a[i]=a[j]; a[j]=w;++i;--j;

}} while (i<=j);

• Po porazdelitvi– levi del tabele: a[k]<x, k=0,1,2,...,j– desni del tabele: a[k]>x, k=i,i+1,...,n– sredina: a[k]=x, k=j+1,...,i-1

Page 28: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 28 - ©Viljan Mahnič

Urejanje s porazdelitvami - Quicksort

• Postopek porazdeljevanja rekurzivno uporabimo na levem in desnem delu tabelepublic static void quicksort(Element[] a){ sort(a,0,a.length-1);}public static void sort(Element[] a, int l, int r){int i=l, j=r;Element x=a[(i+j)/2], w;do{ while (a[i].manjsi(x)) ++i;while (x.manjsi(a[j])) --j;if (i<=j){w=a[i]; a[i]=a[j]; a[j]=w;++i; --j;

}} while (i<=j);if (l<j) sort(a,l,j);if (i<r) sort(a,i,r);

}

Page 29: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 29 - ©Viljan Mahnič

Urejanje s porazdelitvami - Quicksort

• Analiza– vsaka porazdelitev zahteva n primerjanj (pregledati je treba vse

elemente tabele)– pri popolnoma naključni razporeditvi elementov se tabela razdeli

na 2 enaka dela: potrebnih je log2n porazdelitev– celotno število primerjanj je potem n·log2n– v najslabšem primeru (ko je izbrani element x enak največjemu ali

najmanjšemu elementu tabele), je potrebnih n porazdelitev– v tem primeru je celotno število primerjanj n2

• Zaključek– pričakovani čas: TE= o(n·log2n)– najslabši čas: TW=o(n·log2n)

Page 30: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 30 - ©Viljan Mahnič

Urejanje s porazdelitvami - Quicksort

• Primer najslabšega delovanja– določiti želimo tisto permutacijo ključev od 1 do 5, pri kateri se

algoritem najslabše obnaša– vsakokrat bomo za mejo x izbrali največje število– rešitev: 2 4 5 3 1

• Priporočilo (Hoare)– za mejo x izberemo srednjo vrednost majhnega vzorca npr. treh

ključev– bistveno se izboljša delovanje v najbolj neugodnih primerih– na povprečno obnašanje algoritma ta izbira nima posebnega vpliva

Page 31: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 31 - ©Viljan Mahnič

Rekurzija

• Splošne značilnosti– Primer preproste rekurzivne metode: izračun n!

• osnova: zagotavlja prekinitev rekurzije• rekurzivni del

• Preproste rekurzivne metode, ki imajo enostavno iterativno rešitev– binarno iskanje– palindrom– binomski koeficienti

• Uporaba strategije sestopanja– eleganten način za iskanje ene ali vseh možnih rešitev– iskanje vseh permutacij– skakačev obhod

Page 32: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 32 - ©Viljan Mahnič

Rekurzija

• Splošne značilnosti (iz Osnov programiranja 1)– rekurzivna metoda je tista, ki kliče samo sebe– rekurzija omogoča eleganten zapis problemov, ki so definirani

rekurzivno– rekurzije ne smemo zlorabljati: če obstaja za nek problem

preprosta iterativna rešitev, se raje odločimo za iteracijo

• Primer preproste rekurzivne metode: izračun n!(a) 0!=1(b) n! = n·(n-1)!

1! = 1·0! = 1·1 = 12! = 2·1! = 2·1·0! = 2·1·1 = 23! = 3·2! = 3·2·1! = 3·2·1·0! = 3·2·1·1 = 64! = 4·3! = 4·3·2! = 4·3·2·1! = 4·3·2·1·0! = 4·3·2·1·1 = 24 itd.

Page 33: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 33 - ©Viljan Mahnič

Rekurzija

• Zapis ustrezne metode v Javipublic static int f(int n){if (n==0) // osnova (basis)return 1;

else // rekurzivni del (recursive part)return n*f(n-1);

}

• Vsaka rekurzivna metoda mora imeti osnovo in rekurzivni del– osnova zagotavlja, da se rekurzija prekine– rekurzivni del vsebuje rekurzivni klic z argumentom, ki se

spreminja tako, da zagotavlja prekinitev rekurzije

Page 34: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 34 - ©Viljan Mahnič

Rekurzija

• Iterativna rešitevpublic static int f(int n){

int f=1;for (int i=2; i<=n; i++)f*=i;

return f;}

• Nekaj preprostih rekurzivnih programov– binarno iskanje– palindrom– binomski koeficienti– za vse omenjene probleme obstaja preprosta iterativna rešitev

Page 35: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 35 - ©Viljan Mahnič

Rekurzija

• Binarno iskanje: v urejeni tabeli iščemo element x– naj bo t[sr] element, ki se nahaja sredi tabele– če je t[sr] enak x, je iskanje končano– če je t[sr] manjši od x, ponovimo postopek na gornjem delu tabele– če je t[sr] večji od x, ponovimo postopek na spodnjem delu tabele– postopek prekinemo, ko spodnja meja preseže zgornjo

public static int poisci(int[] t, int x, int sp, int zg)

{ if (sp>zg) return -1;int sr=(sp+zg)/2; // izračun sredineif (t[sr]==x)return sr; // element smo našli

else if (t[sr]<x)return poisci(t,x,sr+1,zg); // nadaljujemo v gornji polovici

elsereturn poisci(t,x,sp,sr-1); // nadaljujemo v spodnji polovici

}

Page 36: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 36 - ©Viljan Mahnič

Rekurzija

• Rekurzivna metoda jePalindrom– Niz je palindrom, če je njegova dolžina 0 ali 1– Niz je palindrom, če sta prvi in zadnji znak enaka in je preostanek

niza (brez prvega in zadnjega znaka) tudi palindrom

public static boolean jePalindrom(String n){int d=n.length();if (d<=1)return true;

else if (n.charAt(0)==n.charAt(d-1))return jePalindrom(n.substring(1,d-1));

elsereturn false;

}

Page 37: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 37 - ©Viljan Mahnič

Rekurzija

• Binomski koeficienti– koeficienti, ki jih dobimo pri izračunu potence binoma, npr.

(x +1)6 = x6 + 6x5 + 15x4 + 20x3 + 15x2 + 6x +1– izračunamo jih lahko s pomočjo Pascalovega trikotnika

11 1

1 2 11 3 3 1

1 4 6 4 11 5 10 10 5 1

1 6 15 20 15 6 1

– vsako število znotraj trikotnika je vsota dveh števil nad njim:c(n,k)=c(n-1,k-1)+c(n-1,k) za 0<k<n

n je številka vrstice, k je številka kolone v Pascalovem trikotniku

Page 38: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 38 - ©Viljan Mahnič

Rekurzija

• Zapis ustrezne rekurzivne metodepublic static int binKoef(int n, int k){if (k==0 || k==n) return 1;return binKoef(n-1,k-1)+binKoef(n-1,k);

}

• Iterativna rešitev– uporabimo formulo za kombinacije n elementov po k

k...3211)k2)...(n1)(nn(n

k)!(nk!n!

kn

k)c(n,⋅⋅⋅⋅

+−−−=

−=

=

Page 39: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 39 - ©Viljan Mahnič

Rekurzija

• Primeri, ko je rekurzivna rešitev elegantna, iterativna pa ne– generiranje permutacij, hanojski stolpiči, skakačev obhod, problem

osmih dam

• Generiranje permutacij– napisati želimo program, ki generira vse permutacije števil od 1 do 4– naivni iterativni pristop bi dal naslednjo rešitev:

for (int i1=1; i1<=4; i1++)for (int i2=1; i2<=4; i2++)if (i1!=i2)for (int i3=1; i3<=4; i3++)if (i1!=i3 && i2!=i3) for (int i4=1; i4<=4; i4++)if (i1!=i4 && i2!=i4 && i3!=i4)System.out.println(i1+" "+i2+" "+i3+" “+i4);

Page 40: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 40 - ©Viljan Mahnič

Rekurzija

• Problemi pri tej rešitvi– če povečamo število elementov, moramo

• dodati nove stavke for• dodati nove, še daljše pogoje v stavkih if

– ne moremo napisati splošne rešitve za poljubno število elementov n

• Uporaba rekurzije– napišemo rekurzivno metodo, ki doda število na pozicijo poz

for(int st=1; st<=N; ++st)if (st še ni v permutaciji){

dodaj st v permutacijo;rekurzivno ponovi postopek za naslednjo pozicijo;

}

Page 41: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 41 - ©Viljan Mahnič

Rekurzija

• Predstavitev permutacije: tabela p dolžine Nstatic final int N=4;static int[] p=new int[N];

• Rekurzivna metoda dolociStevilostatic void dolociStevilo(int poz){for(int st=1; st<=N; ++st)if (seNiUporabljeno(st,poz)){p[poz]=st; // dodaj st v permutacijoif (poz==N-1) // osnovaizpisiPermutacijo();

else // rekurzivni deldolociStevilo(poz+1);

}}

Page 42: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 42 - ©Viljan Mahnič

Rekurzija

• Prikaz delovanja: strategija sestopanja (ang. backtracking)

24311,23dolociStevilo(3)4313,42dolociStevilo(2)

42311,2,3,43dolociStevilo(3)2311,22dolociStevilo(2)

3131dolociStevilo(1)konec zanke2dolociStevilo(2)

34211,2,33dolociStevilo(3)42142dolociStevilo(2)

43211,2,3,43dolociStevilo(3)3211,2,32dolociStevilo(2)

211,21dolociStevilo(1)110dolociStevilo(0)

permutacijast v stavku forpozklic

Page 43: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 43 - ©Viljan Mahnič

Rekurzija

• Skakačev obhod– podana je šahovska deska velikosti N x N– skakač se na začetku nahaja na enem izmed polj– obiskati mora vsa polja tako, da se na vsakem polju ustavi samo enkrat

• Z vsakega polja je možnih največ 8 potez

odmiki pri posameznih potezah

a[0]=2; b[0]=1; a[4]=-2; b[4]=-1;

a[1]=1; b[1]=2; a[5]=-1; b[5]=-2;a[2]=-1; b[2]=2; a[6]=1; b[6]=-2;

a[3]=-2; b[3]=1; a[7]=2; b[7]=-1;07

16

x

25

34

Page 44: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 44 - ©Viljan Mahnič

Rekurzija

• Prikaz postopka: zopet uporabimo sestopanjeS 15. polja ne moremo nadaljevati poti, zato sevrnemo za en nivo nazaj in skušamo nadaljevativ drugi smeri.

S 14. polja ne moremo nadaljevati poti, zato sevrnemo za en nivo nazaj in skušamo nadaljevativ drugi smeri.

S 13. polja je nadaljevanje možno, vendar po20. potezi spet zaidemo v slepo ulico.

Vračamo se nazaj in brišemo poteze, dokler nepridemo do 15. polja. Od tam lahko spet nadaljujemo pot v drugi smeri.

72

11615

381

1210514

9413

721520

16116

3811419

1217105

941318

Page 45: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 45 - ©Viljan Mahnič

Rekurzija

• Rekurzivni postopek za izbor naslednje potezedo // zanka za vseh 8 možnih potez{

izberi naslednjo potezo;if (poteza je možna){

zabeleži potezo;if (deska ni polna){

rekurzivno ponovi postopek za naslednjo potezo;if (nadaljevanje ni uspelo) briši potezo;

}}

} while (nadaljevanje ni uspelo && so še možne poteze)

• Bistvo sestopanja: po vrnitvi iz rekurzivne metode ostanemo v zanki in poskušamo nadaljevati v drugi smeri

Page 46: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 46 - ©Viljan Mahnič

Rekurzija

• Dogovori, ki jih upoštevamo pri zapisu v Javi– ponazoritev šahovnice

static final int N=5, NKV=N*N; // velikost šahovnicestatic int[] a=new int[8]; // tabeli odmikovstatic int[] b=new int[8];static int[][] s=new int[N][N]; // šahovnica

s[x][y]==0 // polje še ni bilo obiskanos[x][y]==i // polje je bilo obiskano v i-ti potezi

– izbor argumentovi : zaporedma številka potezevr,st : koordinati polja, s katerega delamo potezo

– izberi naslednjo potezoint k; // indeks v tabelah odmikov a in bint x,y; // koordinati polja, kamor skoči skakačk++; x=vr+a[k]; y=st+b[k]; // izračun naslednjega polja

Page 47: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 47 - ©Viljan Mahnič

Rekurzija

• Dogovori, ki jih upoštevamo pri zapisu v Javi (nadalj.)– poteza je možna

• polje, kamor skoči skakač, mora biti znotraj šahovnice• polje, kamor skoči skakač, ne sme biti še obiskano

if (x<N && x>=0 && y<N && y>=0) // znotraj šahovniceif (s[x][y]==0) // polje še ni bilo obiskano

– zabeleži potezos[x][y]=i;

– briši potezos[x][y]=0;

– deska ni polna i<NKV

– nadaljevanje je uspelometodo sprogramiramo kot funkcijo, ki vrne true, če je skakač prišel do konca

Page 48: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 48 - ©Viljan Mahnič

Rekurzija

• Iskanje vseh možnih rešitev– metoda naslednjaPoteza() se poenostavi

• tudi v primeru, ko je bilo nadaljevanje uspešno, se zanka za izbor naslednje poteze ne prekine

• namesto stavka do...while uporabimo stavek for• metodo lahko sprogramiramo kot proceduro (vračanje vrednosti ni

več potrebno)– ostale spremembe v programu SkakacevObhod2

• izpis rešitve sprogramiramo kot posebno metodo• po izpisu vsake rešitve se izvajanje programa prekine, dokler

uporabnik ne pritisne tipke Enter• zaradi branja podatkov je potreben dodatek throws Exception

Page 49: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 49 - ©Viljan Mahnič

Rekurzija

• Hanojski stolpiči– imamo n obročev različnih velikosti, ki jih moramo prestaviti z ene

palice na drugo– pri tem lahko uporabljamo pomožno palico– manjši obroč lahko postavimo na večjega, ne pa obratno

• Rekurzivni opis problema– prestavimo n-1 obročev z začetne palice na pomožno– prestavimo največji obroč z začetne palice na končno– prestavimo n-1 obročev s pomožne palice na končno

Page 50: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 50 - ©Viljan Mahnič

Rekurzija

• Odprava rekurzije s pomočjo sklada– zahtevke za rekurzijo odlagamo na sklad– sklad (ang. stack) je podatkovna struktura, ki deluje na principu LIFO

(Last-in, First-out)– zahtevke odlagamo na sklad v obratnem vrstnem redu, kot se pojavijo

• Razred Stack iz paketa java.util– empty() funkcija, ki vrne true, če je sklad prazen– peek() funkcija, ki vrne objekt, ki se nahaja na vrhu sklada– pop() funkcija, ki odstrani objekt z vrha sklada (vrne

referenco na odstranjen objekt)– push(objekt) doda objekt na vrh sklada– search(objekt) vrne zaporedno številko objekta (objekt na vrhu

sklada ima številko 1, tisti pod njim številko 2 itd.)

Page 51: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 51 - ©Viljan Mahnič

Rekurzija

• Primer: Hanojski stolpiči– najprej postavimo na sklad začetni zahtevek– nato v zanki vsakokrat odvzamemo s sklada en zahtevek in ga

obdelamo (med obdelavo se lahko na sklad postavijo novi zahtevki)

– postopek ponavljamo dokler sklad ne postane prazen

• Grob opis postopka:postavi začetni zahtevek na sklad;dokler sklad ni prazen{odvzemi zahtevek z vrha sklada;obdelaj zahtevek;

}

Page 52: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 52 - ©Viljan Mahnič

Rekurzija

• Predstavitev zahtevka: vsak zahtevek je objekt s 4 atributi– n : število obročev, ki jih je treba prestaviti– a : izvor– b : pomožna palica– c : ponor

class Zahtevek{public int n;public char a,b,c;

public Zahtevek(int n, char a, char b, char c){this.n=n;this.a=a;this.b=b;this.c=c;

}}

Page 53: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 53 - ©Viljan Mahnič

Rekurzija

• Iterativna verzija metode hanoiprivate static void hanoi(int n, char a, char b, char c){

Stack s=new Stack();s.push(new Zahtevek(n,a,b,c));while (!s.empty()){Zahtevek z=(Zahtevek)s.pop();n=z.n; a=z.a; b=z.b; c=z.c; if (n==1)

System.out.println("Premakni z "+a+" na "+c);else{s.push(new Zahtevek(n-1,b,a,c));s.push(new Zahtevek(1,a,b,c));s.push(new Zahtevek(n-1,a,c,b));

}}

}

Page 54: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 54 - ©Viljan Mahnič

Rekurzija

• Iterativna verzija metode quicksort– Vzdrževati je treba seznam zahtev po porazdelitvah, ki še niso bile

opravljene.– Na vsakem koraku nastaneta 2 zahtevi po porazdelitvi:

• eno obdelamo takoj (tj. zahtevo za levi del tabele)• drugo uvrstimo v seznam (tj. zahtevo za desni del tabele)

– Zahteve v seznamu moramo obravnavati v obratnem vrstnem redu, kot smo jih vstavili: utripajoč sklad.

– Ponazoritev vsake zahteve: z levo in desno mejo tistega dela tabele, znotraj katerega je potrebna nova porazdelitev

– Ponazoritev sklada: uporabimo tabelo, v kateri vsak element ustreza enemu zahtevku

Page 55: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 55 - ©Viljan Mahnič

Rekurzija

• Ponazoritev sklada– uporabimo tabelo, v kateri vsak element ustreza enemu zahtevku

private static class ElementSklada{int l,r;ElementSklada(int l, int r){this.l=l; this.r=r;

}}

final int M=12; // max. število elementov v skladuElementSklada[] sklad=new ElementSklada[M];int s; // vrh sklada – indeks zadnjega zahtevka

Page 56: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 56 - ©Viljan Mahnič

Rekurzijas=0; sklad[0]=new ElementSklada(0,a.length-1);do {

l=sklad[s].l; r=sklad[s].r; s=s-1;do // sprotna obdelave zahtevkov za porazdelitev levega dela{

i=l; j=r; x=a[(l+r)/2];do{

while (a[i].manjsi(x)) ++i;while (x.manjsi(a[j])) --j;if (i<=j){

w=a[i]; a[i]=a[j]; a[j]=w;++i; --j;

}} while (i<=j);if (i<r){

s=s+1; sklad[s]=new ElementSklada(i,r);}r=j;

} while (l<=r);} while (s>=0);

Page 57: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 57 - ©Viljan Mahnič

Rekurzija

• Določitev velikosti sklada– v najslabšem primeru vsebuje desni del en sam element, vsi ostali

so v levem delu. – v tem primeru bi morali na sklad postaviti n zahtev, kar ni

sprejemljivo.

• Rešitev – na sklad postavimo vedno zahtevo po sortiranju večjega dela,

krajši del obdelamo sproti– velikost sklada v tem primeru ne preseže log2n – sprememba je potrebna samo v tistem delu, ki postavlja zahteve na

sklad

Page 58: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 58 - ©Viljan Mahnič

Rekurzija

• Sprememba v tistem delu, ki postavlja zahteve na sklad

if ((j-l)<(r-i)) // levi del je manjši, desni gre na sklad{if (i<r){s=s+1; sklad[s]=new ElementSklada(i,r);

}r=j; // nadaljujemo s porazdeljevanjem levega dela

}else // desni del je manjši, levi gre na sklad{if (l<j){s=s+1; sklad[s]=new ElementSklada(l,j);

}l=i; // nadaljujemo s porazdeljevanjem desnega dela

}

Page 59: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 59 - ©Viljan Mahnič

Razred Vector• Definira zbirko (angl. collection) elementov tipa Object,

ki se obnaša podobno kot tabela– deklariran je v paketu java.util, zato je na začetku programa

potrebno napovedati uporabo tega paketa z import java.util.*;

• Razlike v primerjavi s tabelo– velikost vektorja se po potrebi avtomatsko povečuje– vektor lahko hrani objekte različnih tipov (ker so vsi izpeljani iz

razreda Object)

• Podobno kot pri tabelah in objektih velja, da spremenljivka tipa Vector vsebuje naslov tiste lokacije v pomnilniku, kjer se dejansko nahajajo elementi vektorja.

Page 60: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 60 - ©Viljan Mahnič

Razred Vector• Kreiranje vektorjev: 4 konstruktorji

– konstruktor brez argumentov kreira vektor standardne dolžine 10Vector v=new Vector(); // prazen vektor s kapaciteto 10

– kot argument lahko navedemo zahtevano dolžinoVector v=new Vector(100); // prazen vektor s kapaciteto 100

– poleg začetne dolžine navedemo še prirastek ob vsakem povečanju velikosti (sicer velja, da se ob vsaki potrebi po povečanju velikosti kapaciteta vektorja podvoji).Vector v=new Vector(100,10); // ob vsakem povečanju se

// doda prostor za 10 objektov– kreiramo lahko vektor, ki vsebuje objekte iz neke druge, že obstoječe

zbirke (za zbirke objektov obstaja v javi vmesnik Collection, ki je nadrazred razreda Vector)Vector v=new Vector(c); // c je zbirka objektov tipa// Collection ali nekega drugega, iz Collection izpeljanega tipa

Page 61: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 61 - ©Viljan Mahnič

Razred Vector• Kapaciteta in velikost vektorja

– Kapaciteta (angl. capacity): število objektov, ki jih lahko v določenem trenutku shranimo v vektor (tj. razpoložljiv prostor)

– Velikost (angl. size): število dejansko shranjenih objektov

• Metodi capacity in sizeint kapaciteta=v.capacity(); // trenutna kapacitetaint velikost=v.size(); // trenutna velikostint prostor=v.capacity()-v.size(); // razpoložljiv prostor

• Ostale metode, povezane s kapaciteto in velikostjov.ensureCapacity(150); // če je kapaciteta v manjša od 150, jo

// poveča na 150, v nasprotnem primeru ostane kapacitetea nespremenjenav.setSize(50); // če je velikost manjša od 50, se v elemente do vključno

// petdesetega, vpišejo vrednosti null; če je velkost večja od 50, se vsi // elementi nad 50 izgubijo (ni več referenc, objekti še obstajajo)

v.trimToSize(); // nastavi kapaciteto na dejansko velikost vektorja

Page 62: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 62 - ©Viljan Mahnič

Razred Vector• Shranjevanje objektov v vektor

v.add(novObjekt); // v prvi prost element vektorja v vpiše kazalec na novObjekt; velikost vektorja se poveča za 1; ob uspešnem dodajanju vrne true

v.add(2,novObjekt); // doda novObjekt na pozicijo 2 (pozicije so oštevilčene od 0 dalje); elementi na pozicijah od vključno dva dalje se pomaknejo za eno mesto naprej; vrednost prvega argumenta ne sme biti večja od velikosti vektorja; če je enaka velikosti, gre za dodajanje na prvo prosto pozicijo

v.addElement(novObjekt); // isto kot add(novObjekt), le da ne vrne vrednosti true ali false

v.set(2,novObjekt); // novObjekt "povozi" tistega, ki je bil prej na pozicji 2; metoda vrne kazalec na element, ki je bil prej na tej poziciji

v.addAll(c); // na konec vektorja doda vse elemente iz zbirke cv.addAll(2,c); // na pozicije od vključno 2 dalje vrine vse elemente iz

zbirke c

Page 63: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 63 - ©Viljan Mahnič

Razred Vector

• Branje elementov iz vektorjaDelavec d=(Delavec)v.get(4); // vrne objekt, ki se nahaja na

poziciji 4; potrebna je eksplicitna pretvorba tipa, ker metoda get vrne vrednost tipa Object

Delavec d=(Delavec)v.elementAt(4); // isto kot zgorajDelavec d=(Delavec)v.firstElement(); // vrne prvi elementDelavec d=(Delavec)v.lastElement(); // vrne zadnji element

• Obdelava vseh elementov: podobna zanka kot pri tabelahDelavec d;for (int poz=0; poz<v.size(); ++poz){d=(Delavec)v.get(poz);// sledijo stavki za obdelavo objekta d

}

Page 64: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 64 - ©Viljan Mahnič

Razred Vector

• Prepis elementov iz vektorja v tabelo– Uporaba vektorjev zahteva dodatno režijo, zato je včasih ugodno

prepisati elemente v običajno tabelo. – To lahko naredimo z metodo toArray na dva načina:

• standardno dobimo tabelo z elementi tipa ObjectObject[] delavci=v.toArray();

med obdelavo je treba vsak element tabele pretvoriti v ustrezen tip

• če hočemo dobiti tabelo objektov ustreznega tipa, jo moramo najprej deklarirati// deklaracija tabele ustreznega tipa in ustrezne velikostiDelavec[] delavci=new Delavec[v.size()];

// prepis v tabelov.toArray(delavci);

Page 65: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 65 - ©Viljan Mahnič

Razred Vector• Odstranjevanje elementov iz vektorja

– Pri odstranjevanju elementov se kapaciteta vektorja ne zmanjšuje, manjša se samo velikost.v.remove(3); // odstrani element na poziciji 3; preostali elementi

// se pomaknejo za eno mesto proti začetkuDelavec d=(Delavec)v.remove(3); // metoda remove vrne

// naslov izločenega elementaboolean brisan=v.remove(d); // odstrani prvo nastopanje

// elementa d iz vektorja v; če elementa d ni v vektorju, vrne // false, sicer true

v.removeElementAt(3); // odstrani element na poziciji 3, vendar ne // vrne njegovega naslova

v.clear(); // odstrani vse elementev.removeAll(c); // iz v odstrani vse elemente, ki se nahajajo

// v zbirki c (odstrani vsa nastopanja)

Page 66: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 66 - ©Viljan Mahnič

Razred Vector• Iskanje elementov v vektorju

int poz=v.indexOf(d); // vrne indeks elementa d v vektorju v (če ga ni, vrne -1); za iskanje uporablja metodo equals(), ki jo je treba redefinirati

int poz=v.indexOf(d,5); // išče od vključno pozicije 5 dalje (drugi paramater pove, kje naj se prične iskanje)

int poz=v.lastIndexOf(d); // išče od konca vektorja proti začetkuint poz=v.lastIndexOf(d,5); // išče od pozicije 5 proti začetku

• Primer: želimo poiskati vsa nastopanja objekta d v vektorju vint poz=0;// začetna pozicija za iskanjewhile (poz<v.size() && poz>=0) // dokler je pozicija v mejah vektorja{poz=v.indexOf(d,poz); // poišči naslednjegaif (poz!=-1) // če ga najde{..... // stavki za obdelavo najdenega elementa ++poz; // nova pozicija za iskanje

}}

Page 67: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 67 - ©Viljan Mahnič

Razred Vector• Obhod s pomočjo iteratorja

– V vsaki zbirki lahko definiramo objekt, imenovan iterator, ki omogoča "sprehajanje" po posameznih elementih te zbirke.

– Iterator ima tri metode:next() // vrne naslednji objekt hasNext() // vrne true, če obstaja naslednji objekt remove() // odstrani objekt, ki smo ga dobili ob zadnjem klicu next

• Primer obhodaDelavec d;Iterator it=v.iterator(); // razred Vector podeduje

metodo iterator od razreda AbstractListwhile (it.hasNext()){d=(Delavec)it.next();... // stavki za obdelavo d

}

Page 68: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 68 - ©Viljan Mahnič

Razred Vector• Razred Stack je podrazred razreda Vector

– metode empty, peek, pop, push in search so definirane s pomočjo metod iz razreda Vector

public boolean empty(){ return size()==0;}

public Object peek(){ if (size()==0) throw new EmptyStackException();return elementAt(size()-1);

}

public Object pop(){ Object object=peek();removeElementAt(size()-1);return object;

}

Page 69: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 69 - ©Viljan Mahnič

Razred Vector

public Object push(Object object){ addElement(object);return object;

}

public int search(Object object){ // išče od konca proti začetku// elementi so oštevilčeni tako, da ima vrhnji element številko 1, // tisti pod njim številko 2 itd.int i=lastIndexOf(object);if (i<0) return -1;return size()-i;

}

public Stack() // konstruktor{}

Page 70: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 70 - ©Viljan Mahnič

Zbirke (Collections)

• Collections Framework: hierarhija vmesnikov in razredov za realizacijo različnih zbirk objektov– v paketu java.util– 8 različnih vmesnikov:

• Collection: zbirka objektov• List: seznam (zaporedje) elementov• Set: množica med seboj različnih (ang. unique) elementov• SortedSet: urejena množica med seboj različnih elementov• Map: zbirka parov (ključ,vrednost); ključi morajo biti med

seboj različni• SortedMap: urejena zbirka parov (ključ,vrednost)• Iterator: objekt, s katerim se sprehajamo po zbirki• ListIterator: objekt, s katerim se sprehajamo po seznamu

Page 71: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 71 - ©Viljan Mahnič

Zbirke (Collections)Object

AbstractCollection CollectionAbstractList List

AbstractSequentialListLinkedList

ArrayListVector

StackAbstractSet Set

HashSetTreeSet SortedSet

AbstractMap MapHashMapTreeMap SortedMapWeakHashMap

ArraysBitSet IteratorCollection ListIteratorDictionary

Hashtable MapProperties

Page 72: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 72 - ©Viljan Mahnič

Zbirke (Collections)

• Vmesnik Collectionpublic interface Collection {public boolean add(Object o);// vrne true, če se je vsebina zbirke spremenilapublic boolean addAll(Collection c);// doda objekte iz zbirke c// vrne true, če se je vsebina zbirke spremenilapublic void clear();

public boolean contains(Object o);public boolean containsAll(Collection c);// vrne true, če zbirka vsebuje vse objekte iz zbirke cpublic boolean equals(Object o);

public int hashCode(); // vrne hash kodo zbirkepublic int size();

public boolean isEmpty();

Page 73: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 73 - ©Viljan Mahnič

Zbirke (Collections)

• Vmesnik Collection (nadalj.)public Iterator iterator();// vrne iterator, ki služi za obhod zbirkepublic boolean remove(Object o);

public boolean removeAll(Collection c);// odstrani tiste objekte, ki so v zbirki c// vrne true, če se je vsebina zbirke spremenilapublic boolean retainAll(Collection c);// obdrži samo tiste objekte, ki so v zbirki c// vrne true, če se je vsebina zbirke spremenilapublic Object[] toArray();// prepiše zbirko v tabelo objektovpublic Object[] toArray(Object[] o);// prepiše zbirko v tabelo objektov točno določenega tipa, npr.// String[] x = (String[]) v.toArray(new String[0]);

Page 74: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 74 - ©Viljan Mahnič

Zbirke (Collections)

• Razred AbstractCollection– delna implementacija vmesnika Collection

• javap java.util.AbstractCollection

– implementira, kar se da, ne da bi poznali dejansko pomnilniško strukturo za predstavitev zbirke

– metodi equals() in hashCode() podeduje od razreda Object• njihova redefinicija je prepuščena podrazredom

– metodi iterator() in size() sta še vedno abstraktni• s tem prisilimo podrazrede, da ju definirajo• vseeno ju lahko uporabljamo pri deklaraciji ostalih metod, npr. toString() in isEmpty()

– metoda toString() je redefinirana tako, da med dvema oglatima oklepajema izpiše vsebino vseh objektov v zbirki

Page 75: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 75 - ©Viljan Mahnič

Zbirke (Collections)

• Redefinicija metode toString()public String toString(){ if (isEmpty()) return "[]";Iterator it=iterator();String str="["+it.next;while (it.hasNext())str += ", "+it.next();

return str+"]";}

– za obhod potrebujemo iterator– dejanska deklaracija iteratorja je v podrazredu– pravilen izpis posameznih objektov nam zagotavlja dinamično

povezovanje metode toString()• uporabi se metoda toString() iz tistega razreda, ki mu pripada

objekt, ki ga izpisujemo

Page 76: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 76 - ©Viljan Mahnič

Zbirke (Collections)

• Deklaracija metode isEmpty()– uporabljena je metoda size(), čeprav še ni definirana

public boolean isEmpty(){ return size()==0;

}

• Primer: Razred Bag

– bag (torba) je neurejena zbirka objektov, ki lahko vsebuje duplikate– realizirali jo bomo kot razširitev razreda AbstractCollection– za predstavitev objektov bomo uporabili tabelo

private Object[] objects; // tabela za predstavitev torbeprivate int size=0; // število objektov v torbiprivate static final int CAPACITY=16; // kapaciteta

– iterator bo realiziran s pomočjo notranjega razreda BagIterator

Page 77: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 77 - ©Viljan Mahnič

Zbirke (Collections)

• Notranji razred (ang. inner class)– razred, ki je deklariran znotraj nekega drugega (zunanjega) razreda – ima dostop do vseh spremenljivk zunanjega razreda– običajno je deklariran kot private

private class BagIterator implements Iterator{private int cursor=0;

public boolean hasNext(){ return cursor<size;}public Object next(){ if (cursor>=size) return null;return objects[cursor++];// ob izstopu cursor vsebuje indeks naslednjega elementa

}

Page 78: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 78 - ©Viljan Mahnič

Zbirke (Collections)public void remove()// odstrani objekt, ki smo ga dobili ob zadnjem klicu next// na izpraznjeno mesto prestavi zadnji objekt{ objects[--cursor] = objects[--size];objects[size] = null;

}}

– iterator generiramo kot objekt notranjega razredapublic Iterator iterator(){return new BagIterator();

}

• Anonimni notranji razred– krajši zapis, kadar potrebujemo en sam objekt notranjega razreda– v tem primeru za notranji razred ne potrebujemo imena

Page 79: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 79 - ©Viljan Mahnič

Zbirke (Collections)

public Iterator iterator(){ return new Iterator() // anonimni notranji razred vsebuje samo telo razreda{ private int cursor=0;public boolean hasNext(){ return cursor<size;}public Object next(){ if (cursor>=size) return null;return objects[cursor++];

}public void remove(){ objects[--cursor] = objects[--size];objects[size] = null;

}}; // obvezno podpičje

}

Page 80: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 80 - ©Viljan Mahnič

Zbirke (Collections)

• Vrsta– podatkovna struktura, ki deluje na principu FIFO (First-in, First-out)

• primer: vrsta za nakup vstopnic v kinu– hierarhija vmesnikov in razredov Collections Framework ne vsebuje

posebnega vmesnika oziroma abstraktnega razreda za vrsto– izhajali bomo iz vmesnika Collection, ki mu bomo dodali 4 metode,

tipične za vrsto

import java.util.*;public interface Queue extends Collection{ public Object dequeue(); // odvzame objekt z začetka vrstepublic Object enqueue(Object object); // doda na koncu vrstepublic Object getBack(); // vrne vrednost prvegapublic Object getFront(); // vrne vrednost zadnjega

}

Page 81: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 81 - ©Viljan Mahnič

Zbirke (Collections)

• Primer delovanja vrste

Recimo, da je q objekt tipa vrsta:

q.enqueue("Novak"); [Novak]

q.enqueue("Kranjc"); [Novak, Kranjc]q.enqueue("Petelin"); [Novak, Kranjc, Petelin]q.enqueue("Vidmar"); [Novak, Kranjc, Petelin, Vidmar]

q.dequeue() [Kranjc, Petelin, Vidmar]q.dequeue() [Petelin, Vidmar]q.enqueue("Kajzer"); [Petelin, Vidmar, Kajzer]

Na koncu metoda getFront() vrne niz "Petelin", getBack() pa "Kajzer".

Page 82: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 82 - ©Viljan Mahnič

Zbirke (Collections)

• Dva načina za realizacijo vrste– realizacija s pomočjo tabele– realizacija v obliki dvosmernega seznama

• Hierarhija razredov in vmesnikovObject

AbstractCollection CollectionAbstractQueue Queue

ArrayQueueLinkedQueue

• Razred AbstractQueue– je razširitev razreda AbstractCollection– implementira vmesnik Queue– vsebuje tiste dele rešitve, ki so neodvisni od predstavitve vrste

Page 83: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 83 - ©Viljan Mahnič

Zbirke (Collections)

• Predstavitev s pomočjo tabele: razred ArrayQueueprotected Object[] objects;protected int front=0; // prvo zasedeno mestoprotected int back=0; // prvo prosto mestoprotected int capacity=16; // trenutna kapaciteta

• Tabela objects

0 1 2 3 ... capacity-1frontback

0 1 2 3 front back capacity-1

Page 84: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 84 - ©Viljan Mahnič

Zbirke (Collections)

• Dodajanje v vrsto– nov objekt dodamo v element z indeksom back, back povečamo za 1– če v tabeli ni več prostora, generiramo novo tabelo z dvakrat večjo

kapaciteto in vanjo prepišemo vsebino vrstepublic Object enqueue(Object object){ if (back>=capacity){ Object[] temp = objects;capacity *= 2; // podvojimo kapacitetoobjects = new Object[capacity];for (int i=0; i<back-front; i++)objects[i] = temp[i+front];

back -= front;front = 0;

}objects[back++] = object;return object;

}

Page 85: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 85 - ©Viljan Mahnič

Zbirke (Collections)

• Odvzemanje iz vrste– odvzamemo element z indeksom front in povečamo front za 1– če je leva polovica tabele prazna, pomaknemo vse elemente na

začetek

public Object dequeue(){ if (isEmpty()) throw

new NoSuchElementException("Queue is empty");Object object = objects[front++];if (2*front>=capacity) // pomik v levo{ for (int i=0; i<size(); i++)

objects[i] = objects[i+front];back -= front;front = 0;

}return object;

}

Page 86: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 86 - ©Viljan Mahnič

Zbirke (Collections)

• Iteratorpublic Iterator iterator(){ return new Iterator() // anonimni notranji razred{ private int cursor=front;public boolean hasNext(){ return cursor<back;}public Object next(){ if (cursor>=back) throw

new NoSuchElementException();return objects[cursor++];

}public void remove() // odvzemanje dovolimo samo z metodo// dequeue(), zato metoda remove() ni implementirana{ throw new UnsupportedOperationException();}

};}

Page 87: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 87 - ©Viljan Mahnič

Zbirke (Collections)

• Predstavitev v obliki seznama: razred LinkedQueue– vrsta je predstavljena kot zaporedje elementov, ki so med seboj

povezani v obeh smereh– vsak element seznama (vozlišče) vsebuje

• objekt (naslov objekta)• naslov naslednika• naslov predhodnika

– razred Nodeprivate static class Node{ // atributi vozliščaObject object;Node next, previous;// sledijo deklaracije metod

}

Page 88: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 88 - ©Viljan Mahnič

Zbirke (Collections)

• Prazna vrsta– na začetek seznama kaže "kazalec" header– seznam vsebuje eno samo vozlišče: slepi element– kazalca next in previous kažeta na slepi element

header

null

Page 89: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 89 - ©Viljan Mahnič

Zbirke (Collections)

• Vrsta v splošnemheader

prvi element zadnji elementobj1 objnobj3obj2

null

Page 90: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 90 - ©Viljan Mahnič

Zbirke (Collections)

• Kreiranje vozlišč v seznamu: 2 konstruktorja– konstruktor za slepi element

Node(){ this.next = this.previous = this;}

– konstruktor za vozlišče, ki hrani objektNode(Object object, Node next, Node previous){ this.object = object;this.next = next;this.previous = previous;

}

– prvi konstruktor se kliče na začetku, ko kreiramo prazno vrsto– drugi konstruktor se kliče ob dodajanju objektov v vrsto z metodo enqueue()

Page 91: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 91 - ©Viljan Mahnič

Zbirke (Collections)

• Dodajanje v vrsto– zapomnimo si kazalec na zadnji element– ustvarimo novo vozlišče in vpišemo vrednosti atributov– vzpostavimo povezavi

• od (pred tem) zadnjega elementa naprej• od header-ja nazaj

– povečamo število objektov v vrstipublic Object enqueue(Object object){ Node p = header.previous; // zadnji elementheader.previous=p.next=new Node(object,header,p);++size;return object;

}

Page 92: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 92 - ©Viljan Mahnič

Zbirke (Collections)

• Odvzemanje iz vrste– metoda dequeue() vrne objekt header.next.object

– kazalec na začetek vrste prestavimo na naslednje vozlišče– kazalec previous iz naslednjega vozlišča mora kazati na slepi

element– število objektov v vrsti se zmanjša za 1

public Object dequeue(){ if (isEmpty()) throw new

NoSuchElementException("queue is empty");Object object = header.next.object;header.next = header.next.next;header.next.previous = header;--size;return object;

}

Page 93: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 93 - ©Viljan Mahnič

Zbirke (Collections)

• Iterator– kurzor je tipa Node in na začetku kaže na slepi element– naslednik obstaja, če atribut next v trenutnem vozlišču ne kaže na

slepi element– operacija remove() ni dovoljena; odvzemanje dovolimo samo z

operacijo dequeue()public Iterator iterator(){ return new Iterator() // anonimni notranji razred{ private Node cursor=header;public boolean hasNext(){ return cursor.next != header;}

Page 94: Interdisciplinarni študij Računalništvo in matematika

Osnove programiranja 2 - 94 - ©Viljan Mahnič

Zbirke (Collections)

• Iterator (nadalj.)public Object next(){ if (cursor.next==header) throw new

NoSuchElementException();cursor = cursor.next;return cursor.object;

}

public void remove(){ throw new UnsupportedOperationException();}

};}