Övningen vill visa på vikten av valet av datastruktur, trots att de ofta erbjuder samma funktionalitet genom sina gränssnitt.

Relevanta dokument
TDA550 Objektorienterad programvaruutveckling IT, forts. kurs Övning vecka 5

Sammansatta datatyper Generics: Parametrisk polymorfism

Repetition av OOP- och Javabegrepp

Övning vecka 5. Denna vecka ska vi titta pa samlingar, generics och designmönstren Decorator, Singleton och Iterator.

Hitta k största bland n element. Föreläsning 13 Innehåll. Histogramproblemet

Repetition av OOP- och Javabegrepp

F12 - Collections. ID1004 Objektorienterad programmering Fredrik Kilander

Teoretisk del. Facit Tentamen TDDC (6)

Programmering för språkteknologer II, HT2014. Rum

Objektorienterad Programkonstruktion

Objektorienterad Programkonstruktion. Föreläsning 9 30 nov 2016

Samlingar Collection classes

Sökning. Översikt. Binärt sökträd. Linjär sökning. Binär sökning. Sorterad array. Linjär sökning. Binär sökning Hashtabeller

Abstrakt datatyp. -Algoritmer och Datastrukturer- För utveckling av verksamhet, produkter och livskvalitet.

Datastrukturer, algoritmer och programkonstruktion (DVA104, VT 2015) Föreläsning 6

Föreläsning 14 Innehåll

Föreläsning 9 Innehåll

Föreläsning 4 Datastrukturer (DAT037)

Tentamen Datastrukturer, DAT037 (DAT036)

Övning vecka 6. public void method2() { //code block C method3(); //code block D }//method2

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 3 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Upplägg. Binära träd. Träd. Binära träd. Binära träd. Antal löv på ett träd. Binära träd (9) Binära sökträd (10.1)

DAT043 - föreläsning 8

Datastrukturer och algoritmer. Innehåll. Tabell. Tabell - exempel. Gränsyta till Tabell. Tabell. Modell. Hashtabell Relation, lexikon.

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 9 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Classes och Interfaces, Objects och References, Initialization

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

Länkade strukturer. (del 2)

Classes och Interfaces, Objects och References Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

Objektorienterad Programmering DAT043. Föreläsning 9 12/2-18 Moa Johansson (delvis baserat på Fredrik Lindblads material)

Föreläsning 8 - del 2: Objektorienterad programmering - avancerat

TDDD78 Objektorientering: Lagring och livstid

Objektorienterad programmering med Java, Generics

Det är principer och idéer som är viktiga. Skriv så att du övertygar rättaren om att du har förstått dessa även om detaljer kan vara felaktiga.

Objektorienterad programmering Föreläsning 9. Copyright Mahmud Al Hakim Agenda (halvdag)

Föreläsning 10 Innehåll. Diskutera. Inordertraversering av binära sökträd. Binära sökträd Definition

Programkonstruktion och. Datastrukturer

Obs! Inget ur Javas standardbibliotek får användas i ett svar (om det inte står att man får det).

Länkade strukturer, parametriserade typer och undantag

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 6 Erik Nilsson, Institutionen för Datavetenskap, LiU

Föreläsning 10 Innehåll

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 3 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Datastrukturer, algoritmer och programkonstruktion (DVA104, HT 2014) Föreläsning 5

TENTAMEN: Algoritmer och datastrukturer. Läs detta!

Samlingar, Gränssitt och Programkonstruktion! Förelasning 11!! TDA540 Objektorienterad Programmering!

Subtyping och variance. Objekt-orienterad programmering och design Alex Gerdes, 2018

Arrayer (fält)

TDA550 Objektorienterad programvaruutveckling IT, forts. kurs Övning vecka 5

Tentamen i Algoritmer & Datastrukturer i Java

Abstrakta datatyper. Primitiva vektorer. Deklarera en vektor

Listor. Koffman & Wolfgang kapitel 2, avsnitt , och 2.9

TDDC77 Objektorienterad Programmering

Lösningar Datastrukturer TDA

Objektorienterad programmering E. Algoritmer. Telefonboken, påminnelse (och litet tillägg), 1. Telefonboken, påminnelse (och litet tillägg), 2

Objektorientering: Lagring och livstid

DAT043 - Föreläsning 7

Föreläsning 11 Innehåll. Diskutera. Binära sökträd Definition. Inordertraversering av binära sökträd

Föreläsning 10 Innehåll

Föreläsning 10 Innehåll. Diskutera. Hashtabeller. Hashfunktion. hashfunktion. hashkod (ett heltal)

Föreläsning 5 Innehåll

Lägg uppgifterna i ordning. Skriv uppgiftsnummer och din anmälningskod överst i högra hörnet på alla papper.

Föreläsning 2 Datastrukturer (DAT037)

Föreläsning 2 Datastrukturer (DAT037)

Algoritmer. Två gränssnitt

Programmering för språkteknologer II, HT2011. Rum

Algoritmer och datastrukturer 2012, fo rela sning 8

F9 - Polymorfism. ID1004 Objektorienterad programmering Fredrik Kilander

Tentamen Datastrukturer (DAT037)

Föreläsning 8. Mängd, Avbildning, Hashtabell

TENTAMEN: Objektorienterad programmering. Läs detta! Skriv din tentamenskod på varje blad (så att vi inte slarvar bort dem).

Diskutera. Hashfunktion

Tommy Färnqvist, IDA, Linköpings universitet

Ett problem. Kontrollstrukturer och arrayer. Arrayer. Lösningen. Arrayer och hakparanteser. Exempel int[] results; results = new int[10]; // 0..

Objekt, klasser. Tillstånd Signatur Kommunikation Typ. Fält, parametrar och lokala variabler. Konstruktorer Metoder DAVA15

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 4 Erik Nilsson, Institutionen för Datavetenskap, LiU

Föreläsning REPETITION & EXTENTA

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 11 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Tentamen Datastrukturer D DAT 035/INN960

Föreläsning 4 Innehåll. Abstrakta datatypen lista. Implementering av listor. Abstrakt datatypen lista. Abstrakt datatyp

Föreläsning 7. Träd och binära sökträd

Sökning och sortering

Exempel. Arrayer. Lösningen. Ett problem. Arrayer och hakparanteser. Arrayer

Föreläsning 7 Innehåll. Rekursion. Rekursiv problemlösning. Rekursiv problemlösning Mönster för rekursiv algoritm. Rekursion. Rekursivt tänkande:

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 6 Erik Nilsson, Institutionen för Datavetenskap, LiU

Trädstrukturer och grafer

Tentamen Grundläggande programmering

1.1 Runnable och Thread

Programmering för språkteknologer II, HT2011. Rum

Arrayer. results

Lösningsförslag för tentamen i Datastrukturer (DAT037) från

Föreläsning 6 Datastrukturer (DAT037)

Den som bara har en hammare tror att alla problem är spikar

TDDC Terminologi Uppdaterad Fö #1

Intro till standardbiblioteket. Eric Elfving

TDDC30 Programmering i Java, Datastrukturer och Algoritmer Lektion 2. Länkade listor Stackar Köer MyList Iteratorer Lab 2 Exceptions Paket

Objektorientering: Lagring, räckvidd och livstid

Föreläsning 5 Datastrukturer (DAT037)

Tommy Färnqvist, IDA, Linköpings universitet. 1 ADT Map/Dictionary Definitioner Implementation... 2

Arv: Fordonsexempel. Arv. Arv: fordonsexempel (forts) Arv: Ett exempel. En klassdefinition class A extends B {... }

Tentamen Datastrukturer, DAT037 (DAT036)

Transkript:

1 Samlingar 1.1 Frekvenstabell En Integer är icke-muterbar (precis som String, Float, Boolean et.c.). Ickemuterbarhet har många fördelar, men en nackdel är att ett helt nytt objekt måste skapas när ett nytt värde ska lagras, något som kan dra ned programmets prestanda. Ett frekvensvärde i uppgift 2 lagras som en Integer och när ett sådant värde ökas, är det alltså istället ett nytt objekt med det högre värdet som skapas. Vid testkörning av programmet w5/ex1/frequencytable/sol/histogramtest är skillnaden inte särskilt stor 1 (givetvis lite beroende på mängden unika nycklar). Provkör gärna och se vad du får för skillnad. Typiskt hos mig är att Histogram1 kör på 1.6 sekunder och Histogram2 kör på 2.4 sekunder per test. 1.2 Iteratorrättning 1.3 En exklusiv union 1.4 Under huven Övningen vill visa på vikten av valet av datastruktur, trots att de ofta erbjuder samma funktionalitet genom sina gränssnitt. En länkad lista (x) är som synes bäst för tillägg av innehåll (add) medan den är betydligt sämre än de andra två andra på att söka upp (contains) ett lagrat element. Detta beror på att allting i en länkad lista läggs på rad, med bara direkt tillgång till första (och ev. sista) elementet i denna rad. Att lägga till ett element är därför lätt, men att hitta det kräver att programmet börjar i ena änden av raden och går igenom ett element i taget, i värsta fall kan det därför behöva stega sig igenom alla. 1... på min maskin, Pentium i5, GNU/Linux 3.0.0-13-generic x86 64, OpenJDK 64-bit Server VM 1.6.0 23 1

Figur 1: Antal steg för olika datastrukturer som en funktion av antal element de innehåller (n), något förenklat. Struktur Mean add Worst add Mean contains Worst contains Länkad lista 1 1 n/2 n Balanserat träd log 2 (n) log 2 (n) log 2 (n) 1 log 2 (n) Hashtabell 1 n 1 1 n Ett träd (y) visar sig ungefär lika bra vid tillägg och sökningar. Trädet lagrar sina element i form av, ja just det, ett träd :) I förhållande till den länkade listan behöver den (förmodligen) inte gå lika lång väg, den börjar vid trädets rot och letar sig steg för steg ut till rätt gren. Detta behöver den göra vid både tillägg och sökning, och därför tar dessa ungefär lika lång tid. Vid tillägg behöver den ev. också ändra på trädets struktur för att det ska fortsätta vara just ett träd (i värsta fall skulle ett träd annars kunna bli en länkad lista, d.v.s. alla grenar ligger på en rad efter varandra). Denna omstrukturering kallas för balansering 2. För att kunna avgöra var elementen ska lagras måste de kunna jämföras med varandra (d.v.s. implementera Comparable<T> i Java). En hashtabell (z) ter sig i det här testet som det bästa alternativet, även om länkade listan slår den för tillägg. Dess snabbhet beror på att den internt använder sig av en array, men den kan ändå inte garantera att alla element lagras på olika positioner. Flera element som lagras på samma position läggs därför i en länkad lista. Om (teoretiskt) alla element lagrades på en position skulle alltså en hashtabell degraderas till en enda länkad lista och heller inte prestera bättre. Utmaningen ligger därför i att försöka placera elementen så jämt över arrayens positioner som möjligt. En position i en array nås som vanligt genom dess index, alltså ett positivt heltal. För att bestämma indexet för ett element utförs ofta en beräkning som involverar elementets inneboende tillstånd (känns det bekant? i Java används metoden hashcode() som ju alla objekt innehåller). Varför används då träd överhuvudtaget om hashtabellen ändå presterar bättre? Ett träd har ytterligare en egenskap, det håller elementen sorterade. Dessutom är värsta falls-beteendet för hashtabeller linjär, d.v.s. det kan bli lika dyrt att söka som i en länkad lista. Skillnaden mellan förväntad genomsnittstid kontra värsta falls-tid kan ses i figur 1.4 där n är antalet befintliga element i strukturen. Vi antar också att de träd vi använder garanterat är balanserade, vilket är fallet med t.ex. TreeSet och TreeMap. Genomsnittsfallet för hashtabeller är något förenklat men är inte en funktion av antalet element utan av fyllnadsgraden hos tabellen. 2 För mer information, se kurser i datastrukturer och algoritmer. 2

2 Generics 2.1 Typsäkerhet Lösning Se programkod. Programmet krashar då en Bicycle inte har Car som superklass. Då programmet kommer till det element som är en Bicycle i vehicles blir det ClassCastException; en cykel släpper inte ut koldioxid (annat än möjligen genom cyklisten själv). Då vi använder råa typer, d.v.s. vi utelämnar den möjliga typparametern finns det ingen möjlighet för kompilatorn att lista ut att vi vid ett senare tillfälle förväntar oss att det endast finns objekt av en given typ i samlingen. Lösningen blir alltså att inskränka samlingen genom att istället deklarera variabeln Collection<Car> vehicles = new HashSet<Car>;. Nu kompilerar programmet inte om man försöker lägga till t.ex. en cykel. 3

3 Singleton-mönstret Lösning Se programkod. Klassen är inte en singleton eftersom flera instanser kan skapas av klassen. För att göra klassen till en singleton skulle följande behöva förändras: Genom att istället göra en enum av klassen blir det omöjligt att skapa instanser av den. Notera semikolonet som indikerar att listan av enumelement är slut. Detta är alltså en enum utan enum-element! För ett mer utvecklat resonemang, se gärna Item 3 i Joshua Bloch s Effective Java. Det finns dock inget att tjäna på att göra klassen till en singleton eftersom det inte finns något tillstånd som behöver initieras vid ett bestämt tillfälle. 3 Men eftersom klassen bara innehåller statiska metoder bör den inte gå att instansiera överhuvudtaget. Att göra den till en enum hindrar oss också från att kunna skapa instanser genom deserialisering 4. Att göra en vanlig klass med privat konstruktor skyddar oss inte från detta. Detta har ingenting med singleton egenskapen att göra men... Då denna veckas övningar delvis handlar om generics, studera generaliseringen som gjorts i GameUtils. Det är onödigt oflexibelt att bara kunna skapa och fylla fält av fält av GameTile. Genom några små förändringar har vi nu åstadkommit metoder som kan fylla och skapa fält av fält av vilken referenstyp som helst. Om vi bytt ut typparametern T mot klassnamnet Object hade vi kunna blanda element helt på måfå. Som metoderna ser ut nu kan vi bara fylla dem med element av just typen T. 3 Det finns mycket kritik mot designmönstret Singleton, till stor del p.g.a. att en singleton innebär införande av ett globalt tillstånd. För att läsa mer, gör en internetsökning, det har diskuterats ordentligt... 4 Se http://en.wikipedia.org/wiki/serialization#java 4

4 En udda dekoratör och iterator Klassen hade kunnat användas som iterator till en svagt icke-muterbar samling, d.v.s. åtkomst till samlingens ingående objekt tillåts (vilka kan vara muterbara), men samlingen själv går inte att förändra. Java har t.ex. till skillnad från C++ 5 en hårt specificerad design av sin iterator. Det hade varit naturligare om denna delats upp på flera klasser, där den minsta klassen bara erbjudit metoderna nästa och harnästa. Större varianter skulle då inkludera fler operationer. Som övningen visar, tvingas vi i Java att erbjuda möjligheten att ta bort element med iteratorn (såvida inte remove() fulhackas bort genom exception-kastning). Dessutom går det bara att stega framåt, inte bakåt. Eftervillkoren för de två metoderna skiljer sig åt såtillvida att processiterator(forwardinputiterator<t>) omöjligen kan mutera den underliggande strukturen; remove är ju borta. Det tråkiga med denna lösning är att vi får ett körningsfel om vi försöker anropa remove i metoden processiterator(iterator<t>) med en ForwardInputIterator. 5 http://www.cplusplus.com/reference/std/iterator/ 5