Tietorakenteet, laskuharjoitus 8, malliratkaisut

Samankaltaiset tiedostot
Tietorakenteet, laskuharjoitus 8,

Listarakenne (ArrayList-luokka)

private TreeMap<String, Opiskelija> nimella; private TreeMap<String, Opiskelija> numerolla;

16. Javan omat luokat 16.1

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Taulukot & Periytyminen

Ohjelmistojen mallintaminen viikon 4 laskareiden mallivastauksia

JAVA-PERUSTEET. JAVA-OHJELMOINTI 3op A JAVAN PERUSTEET LYHYT KERTAUS JAVAN OMINAISUUKSISTA JAVAN OMINAISUUKSIA. Java vs. C++?

Java-kielen perusteet

Metodien tekeminen Javalla

Kääreluokat (oppikirjan luku 9.4) (Wrapper-classes)

Tietorakenteet. JAVA-OHJELMOINTI Osa 5: Tietorakenteita. Sisällys. Merkkijonot (String) Luokka String. Metodeja (public)

Informaatioteknologian laitos Olio-ohjelmoinnin perusteet / Salo

15. Ohjelmoinnin tekniikkaa 15.1

Java-kielen perusteet

Ohjelmoinnin jatkokurssi, kurssikoe

20. Javan omat luokat 20.1

Sisällys. 20. Javan omat luokat. Java API. Pakkaukset. java\lang

Olio-ohjelmointi Javalla

15. Ohjelmoinnin tekniikkaa 15.1

5. Hajautus. Tarkastellaan edelleen sivulla 161 esitellyn joukkotietotyypin toteuttamista

9. Periytyminen Javassa 9.1

(a) L on listan tunnussolmu, joten se ei voi olla null. Algoritmi lisäämiselle loppuun:

Luokka Murtoluku uudelleen. Kirjoitetaan luokka Murtoluku uudelleen niin, että murtolukujen sieventäminen on mahdollista.

Ohjelmointi 2 / 2008 Välikoe / Pöytätestaa seuraava ohjelma.

Java-kielen perusteet

7. Näytölle tulostaminen 7.1

17. Javan omat luokat 17.1

Taulukot. Jukka Harju, Jukka Juslin

Ohjelmoinnin perusteet Y Python

9. Periytyminen Javassa 9.1

Hajautus. operaatiot insert ja search pyritään tekemään erittäin nopeiksi

Muuttujat ja kontrolli. Ville Sundberg

Rajapinta (interface)

Vertailulauseet. Ehtolausekkeet. Vertailulauseet. Vertailulauseet. if-lauseke. if-lauseke. Javan perusteet 2004

ITKP102 Ohjelmointi 1 (6 op)

Algoritmit 2. Luento 3 Ti Timo Männikkö

Sisällys. 9. Periytyminen Javassa. Periytymismekanismi Java-kielessä. Periytymismekanismi Java-kielessä

Ohjelmointi 2, välikoe

Javan perusteet. Ohjelman tehtävät: tietojen syöttö, lukeminen prosessointi, halutun informaation tulostaminen tulostus tiedon varastointi

11. Javan valintarakenteet 11.1

Sisältö. 2. Taulukot. Yleistä. Yleistä

Yleistä. Nyt käsitellään vain taulukko (array), joka on saman tyyppisten muuttujien eli alkioiden (element) kokoelma.

Sisältö. 22. Taulukot. Yleistä. Yleistä

Tietorakenteet, laskuharjoitus 7,

List-luokan soveltamista. Listaan lisääminen Listan läpikäynti Listasta etsiminen Listan sisällön muuttaminen Listasta poistaminen Listan kopioiminen

Algoritmit 1. Demot Timo Männikkö

Ohjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti:

Algoritmit 2. Luento 3 Ti Timo Männikkö

17. Javan omat luokat 17.1

Periytyminen (inheritance)

Tietorakenteet, laskuharjoitus 7, ratkaisuja

A) on käytännöllinen ohjelmointitekniikka. = laajennetaan aikaisemmin tehtyjä luokkia (uudelleenkäytettävyys)

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op. Tietorakenneluokkia 2: HashMap, TreeMap

Ohjelmointitaito (ict1td002, 12 op) Kevät Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen

Ohjelmointi 2 / 2010 Välikoe / 26.3

Tietorakenteet, laskuharjoitus 6,

Olio-ohjelmointi Syntaksikokoelma

815338A Ohjelmointikielten periaatteet Harjoitus 5 Vastaukset

Testivetoinen ohjelmistokehitys

18. Abstraktit tietotyypit 18.1

Harjoitus Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:

Luokan sisällä on lista

Taulukot. Taulukon määrittely ja käyttö. Taulukko metodin parametrina. Taulukon sisällön kopiointi toiseen taulukkoon. Taulukon lajittelu

Tietorakenteet, laskuharjoitus 3, ratkaisuja

Sisällys. 9. Periytyminen Javassa. Periytymismekanismi Java-kielessä. Periytymismekanismi Java-kielessä

812341A Olio-ohjelmointi Peruskäsitteet jatkoa

ITKP102 Ohjelmointi 1 (6 op)

Algoritmit 1. Demot Timo Männikkö

Rinnakkaisohjelmointi kurssi. Opintopiiri työskentelyn raportti

// Tulostetaan double-tyyppiseen muuttujaan "hinta" tallennettu // kertalipun hinta ja vaihdetaan riviä. System.out.printf("%.1f euros.

Sisällys. 18. Abstraktit tietotyypit. Johdanto. Johdanto

14. Poikkeukset 14.1

Metodit. Metodien määrittely. Metodin parametrit ja paluuarvo. Metodien suorittaminen eli kutsuminen. Metodien kuormittaminen

T Henkilökohtainen harjoitus: FASTAXON

Java kahdessa tunnissa. Jyry Suvilehto

Mikä yhteyssuhde on?

Operaattoreiden ylikuormitus. Operaattoreiden kuormitus. Operaattoreiden kuormitus. Operaattoreista. Kuormituksesta

14. Poikkeukset 14.1

Javan perusteita. Janne Käki

Sisällys. 14. Poikkeukset. Johdanto. Johdanto

4. Hajautus. Hajautus (hashing) on vaihtoehto tasapainoisille puille dynaamisen joukon toteuttamisessa:

Sisällys. JAVA-OHJELMOINTI Osa 7: Abstrakti luokka ja rajapinta. Abstraktin luokan idea. Abstrakti luokka ja metodi. Esimerkki

Kompositio. Mikä komposition on? Kompositio vs. yhteyssuhde Kompositio Javalla Konstruktorit set-ja get-metodit tostring-metodi Pääohjelma

Sisällys. 1. Omat operaatiot. Yleistä operaatioista. Yleistä operaatioista

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä. Tiedonkätkentä. Aksessorit. 4.2

Algoritmit 2. Luento 14 Ke Timo Männikkö

Java-kielen perusteita

ITKP102 Ohjelmointi 1 (6 op), arvosteluraportti

Sisällys. 14. Poikkeukset. Johdanto. Johdanto

CoMa - Ohjelmoinnin tyyliohje

Tietorakenteet (syksy 2013)

ITKP102 Ohjelmointi 1 (6 op)

Olion elinikä. Olion luominen. Olion tuhoutuminen. Olion tuhoutuminen. Kissa rontti = null; rontti = new Kissa();

// Tulostetaan double-tyyppiseen muuttujaan "hinta" tallennettu // kertalipun hinta ja vaihdetaan riviä. System.out.printf("%.1f euros.

Algoritmit 2. Luento 4 To Timo Männikkö

Pakkauksen kokoaminen

1. Kun käyttäjä antaa nollan, niin ei tulosteta enää tuloa 2. Hyväksy käyttäjältä luku vain joltain tietyltä väliltä (esim tai )

1. Omat operaatiot 1.1

TIETORAKENTEET JA ALGORITMIT

58131 Tietorakenteet ja algoritmit (kevät 2016) Ensimmäinen välikoe, malliratkaisut

Transkriptio:

Tietorakenteet, laskuharjoitus 8, malliratkaisut 1. Seuraavassa on yksi tapa toteuttaa metodit hashcode ja equals: public int hashcode() { return this.x * 31 + this.y; public boolean equals(object o) { if (!(o instanceof Kordinaatti)) return false; Kordinaatti v = (Kordinaatti)o; if (this.x!= v.x) return false; if (this.y!= v.y) return false; return true; 2. Seuraavassa on yksi tapa toteuttaa metodit hashcode ja equals: public int hashcode() { int koodi = this.postinumero; koodi = koodi * 29 + katu.tolowercase().hashcode(); koodi = koodi * 29 + kaupunki.tolowercase().hashcode(); return koodi; public boolean equals(object o) { if (!(o instanceof Osoite)) return false; Osoite v = (Osoite)o; if (this.postinumero!= v.postinumero) return false; if (!this.katu.equalsignorecase(v.katu)) return false; if (!this.kaupunki.equalsignorecase(v.kaupunki)) return false; return true; 3. Ylivuotoketjuihin ja avoimeen hajautukseen perustuvat hajautustaulut toteutettiin yhteisen yliluokan avulla, joka helpotti yhteisen toiminnallisuuden jakamista. Luokalla on mm. edellisessä tehtävässä esitellyt metodit. import java.util.arraylist; import java.math.biginteger; // Yliluokka avoimelle ja ylivuotoketjuja käyttävälle hajautukselle abstract class HajautusTaulu { 1

/* Eri hajautusfunktioiden tyypit */ public enum hajautus {UNIV, KERTO, JAKOJ public static final double MAGIC = 0.6180339887498948; public static final BigInteger BIGPRIME = new BigInteger("2147483647"); protected int koko; protected hajautus haj; //ensisijainen hajautusfunktio //universaalihajautuksen parametrit protected int a; protected int b; public int annakoko() { return this.koko; protected int kerto_haj(int num) { return (int) Math.floor(this.koko*murto_osa(MAGIC*num)); protected int jakoj_haj(int num) { return num % this.koko; protected int universaali_haj(int num) { protected int hash(int avain, hajautus haja) { int arvo = 0; switch(haja) { case JAKOJ: arvo = jakoj_haj(avain); break; case KERTO: arvo = kerto_haj(avain); break; case UNIV: arvo = universaali_haj(avain); break; return arvo; public static double murto_osa(double num) { 2

return num - Math.floor(num); public static ArrayList<Integer> alkuluvut(int max) { public static int alukulahelta(int luku) { public static int stringtoint(string mjono) { Koska Java ei tue etumerkittömiä kokonaislukuja pitää avoimessa hajautuksessa olla hyvin tarkkana törmäysten sattuessa. Jos luku vuotaa yli, niin se pyörähtää ja saa hyvin pienen negatiivisen arvon. Javassa %-operaattori (jakojäännös) voi myös palauttaa negatiivisen arvon, joten lukujen oikeellisuus pitää tarkistaa käsin. Ylivuotoketjuja käyttävän hajautustaulun toteutus on Javassa melko suoraviivaista, koska apuna voidaan käyttää kirjastosta löytyviä valmiita toteutuksia linkitetyille listoille. Hajautustaulujen toteutukset ovat tiedostoissa HajautusTauluA (avoin hajautus) sekä HajautusTauluK (ylivuotoketjuja käyttävä hajautus). 4. Kuhunkin erityyppiseen hajautustauluun lisättiin kaikki Aleksis Kiven Seitsemän veljestä-romaanissa esiintyneet sanat. Kuvassa 1 on esitetty lisäyksiin kulutettu aika. Tarkastelemalla tuloksia havaitaan, että eräs kaksoishajautuksella toteutettu avoin hajautustaulu sattui olemaan erittäin hidas verrattuna muihin. Tämä selittyy luultavasti sillä, että törmäysten yhteensattuessa kaksoishajautuksella saatu kokeilujono on huono. Tämänlainen tilanne syntyy esimerkiksi silloin, jos n:n mittaisessa taulukossa kaksoishajautusfunktio palauttaa arvon n/2. Testeissä avointa hajautusta kokeiltiin myös 30000:n kokoisella taulukolla, mutta ne eivät mahtuneet kuvaan koska suoritus kesti niillä 10-30 kertaa enemmän kuin kuvassa esitetyillä tauluilla. Tämä johtuu siitä, että tällöin kokeilujonot ovat hyvin pitkiä. Kuvassa 2 on esitetty keskimääräinen ylivuotoketjun pituus kun käytetään ylivuotoketjuja. Empiiriset tulokset vahvistavat, että ylivuotoketjut kasvavat taulukon koon pienetessä. Aineistossa oli noin 30000 eri sanaa, joten hajautusfunktiot ovat onnistuneet jakamaan avaimet keskimäärin melko hyvin. 3

Lisäyksiin kulunut aika 135.5 144.7 111.6 112.9 107.5 105.5 111.2 110.7 110.3 111.7 103.9 101.3 121.5 423.5 118.6 117 116.1 112.2 109.4 159.4 144.9 140.2 123.9 117.9 114.3 115.6 110.7 106.6 153.6 106.7 Avoin: universaali, lineaarinen (40000) Avoin: universaali, lineaarinen (50000) Avoin: kertolasku, lineaarinen (40000) Avoin: kertolasku, lineaarinen (50000) Avoin: jakojäännös, lineaarinen (40009) Avoin: jakojäännös, lineaarinen (49999) Avoin: universaali, neliöllinen (40000) Avoin: universaali, neliöllinen (50000) Avoin: kertolasku, neliöllinen (40000) Avoin: kertolasku, neliöllinen (50000) Avoin: jakojäännös, neliöllinen (40009) Avoin: jakojäännös, neliöllinen (49999) Avoin: universaali, kertolasku (40000) Avoin: universaali, kertolasku (50000) Avoin: universaali, kertolasku (50001) Avoin: kertolasku, universaali (40000) Avoin: kertolasku, universaali (50000) Avoin: jakojäännös, kertolasku (40009) Avoin: jakojäännös, kertolasku (49999) Ylivuotokeju: universaali (5000) Ylivuotokeju: universaali (10000) Ylivuotokeju: universaali (15000) Ylivuotokeju: kertolasku (5000) Ylivuotokeju: kertolasku (10000) Ylivuotokeju: kertolasku (15000) Ylivuotokeju: jakojäännös (4999) Ylivuotokeju: jakojäännös (10007) Ylivuotokeju: jakojäännös (15013) TreeSet HashSet 0 100 200 300 400 ms Kuva 1: Lisäyksiin kulunut aika 4

Ylivuotoketjujen keskimääräiset pituudet 6.2113 3.255 2.3734 6.2128 3.2512 2.3734 Ylivuotokeju: universaali (5000) Ylivuotokeju: universaali (10000) Ylivuotokeju: universaali (15000) Ylivuotokeju: kertolasku (5000) Ylivuotokeju: kertolasku (10000) Ylivuotokeju: kertolasku (15000) Ylivuotokeju: jakojäännös (4999) Ylivuotokeju: jakojäännös (10007) Ylivuotokeju: jakojäännös (15013) 6.2079 3.2539 2.3705 0 1 2 3 4 5 6 ylivuotoketjun keskimääräinen pituus Kuva 2: Ketjujen keskimääräiset pituudet käytettäessä ylivuotoketjuja 5

5. Edellisessä tehtävässä oli jo vertailtu Javan valmista kalustoa (HashSet, TreeSet) lisäysten tapauksessa. Kuvassa 3 on esitetty hakuihin kulunut aika, kun Seitsemän veljesten sanojen joukosta koitettiin hakea jokaista Dostojevskin Rikos ja Rangaistusromaanin englanninkielisessä versiossa esiintyvää sanaa. Ensimmäiseksi havaitaan, että hakuun kului huomattavasti vähemmän aikaa kuin lisäykseen. Tämä johtuu siitä, että haun yhteydessä ei tarvi jatkuvasti kopioida merkkijonoja talteen. Tuloksissa ei näy silmiinpistäviä eroja. Ehkä kiinnostavin tulos on, että Javan HashSet tuntuisi olevan ainakin lisäyksissä sekä hauissa nopampi kuin TreeSet kun talletettavana on merkkijonoja. Hakuihin kulunut aika 21.3 18 15.5 16 18.7 14.9 16 14.7 16 14.4 15 13.6 22.6 179.4 17.1 17.6 15.6 15.4 14.3 18.4 15.9 16.1 18.4 16.4 15.9 18.5 15.8 15.5 16.6 13.4 Avoin: universaali, lineaarinen (40000) Avoin: universaali, lineaarinen (50000) Avoin: kertolasku, lineaarinen (40000) Avoin: kertolasku, lineaarinen (50000) Avoin: jakojäännös, lineaarinen (40009) Avoin: jakojäännös, lineaarinen (49999) Avoin: universaali, neliöllinen (40000) Avoin: universaali, neliöllinen (50000) Avoin: kertolasku, neliöllinen (40000) Avoin: kertolasku, neliöllinen (50000) Avoin: jakojäännös, neliöllinen (40009) Avoin: jakojäännös, neliöllinen (49999) Avoin: universaali, kertolasku (40000) Avoin: universaali, kertolasku (50000) Avoin: universaali, kertolasku (50001) Avoin: kertolasku, universaali (40000) Avoin: kertolasku, universaali (50000) Avoin: jakojäännös, kertolasku (40009) Avoin: jakojäännös, kertolasku (49999) Ylivuotokeju: universaali (5000) Ylivuotokeju: universaali (10000) Ylivuotokeju: universaali (15000) Ylivuotokeju: kertolasku (5000) Ylivuotokeju: kertolasku (10000) Ylivuotokeju: kertolasku (15000) Ylivuotokeju: jakojäännös (4999) Ylivuotokeju: jakojäännös (10007) Ylivuotokeju: jakojäännös (15013) TreeSet HashSet 0 50 100 150 ms Kuva 3: Hakuihin kulunut aika Iteraattoreita voidaan käyttää Javassa kahdella eri tavalla. Ensimmäisessä tavassa niitä käytetään suoraan Iterator-olion välityksellä. Seuraava koodinpätkä käy läpi TreeSet<String>-tyyppiä olevan puu-muuttujan avaimet kasvavassa järjestyksessä. import java.util.iterator Iterator<String> iter = puu.iterator(); while(iter.hasnext()) 6

System.out.println(iter.next()); Jos Javan olio toteuttaa Iterable-rajapinnan niin iteraattoria voidaan käyttää myös niin kutsutun for-each-silmukan avulla. Seuraava koodi tekee tismalleen saman kuin edellinenkin. //ei tarvitse importata Iterator-luokkaa for(string mjono : puu) System.out.println(mjono); Koska Javan TreeSet on järjestetty joukko niin iteraattori käy avaimet läpi kasvavassa järjestyksessä. Jos sama tehdään HashSet-oliolle niin avaimet tulostuvat mielivaltaisessa järjestyksessä. Kirjojen yhteisten sanojen tulostus ainoastaan kerran voitaisiin suorittaa käyttämällä kahta hajautustaulua. Toiseen talletettaisiin Seitsemässä veljeksessä esiintyvät sanat ja toiseen talletettaisiin jo kertaalleen tulostetut sanat. 7