Algoritmer och datastrukturer, förel. 1 Algoritmer och datastrukturer Introduktion Föreläsning 1 (Weiss kap. 1-4) Introduktion till kursen Exempel: Datastrukturen ”mängd” Generiska<klasser> De flesta datastrukturerna i kursen definieras som generiska klasser ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Många begrepp blir det … Algoritmer och datastrukturer, förel. 1 Algoritmanalys Tidskomplexitet Datastruktur O(N log N) Generisk klass Hashtabell Divide & Conquer Prioritetskö Worst case Begreppskultur Viktigt i sig! ADT ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
”Den som bara har en hammare tror att alla problem är spikar” Algoritmer och datastrukturer, förel. 1 ”Den som bara har en hammare tror att alla problem är spikar” Repertoaren avgör vilka problem man kan lösa Det räcker inte att kunna syntaxen för ett programmeringsspråk © Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Vilken loop är snabbast? Algoritmer och datastrukturer, förel. 1 Vilken loop är snabbast? for ( i = 0; i < n; i++ ) { for ( j = 0; j < n; j++ ) { // massa jobb ... } for ( j = i; j < n; j++ ) { 1 2 TAVLAN Den andra är dubbelt så snabb, men ... Låt T(N) = antalet gånger som ”massa job” startar T1(10) = 100 T1(20) = 400 T1(100) = 10.000 T2(10) = 55 = 10+9+…+1 = sum_1^N(k) = N(N+1)/2 T2(20) = 210 T2(100) = 5050 ”kvalitativt” är de lika detaljoptimering t.ex. flytta arbete ur inre loopen T(N) är proportionellt mot N2 i båda fallen! Inblickar: Komplexitetsanalys, tillämpn. RSA ... VS datorprestanda ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Vad kan man ha en datastruktur till? Algoritmer och datastrukturer, förel. 1 Vad kan man ha en datastruktur till? Problem: Skriv ut en serie inlästa tal utan duplikat Ex. indata 4 1 3 1 2 1 4 3 skall ge utskriften 4 1 3 2 Informell algoritm: Så länge det finns mer indata Läs N Om N ej ”är utskrivet tidigare” Skriv ut N ”Kom ihåg” N … det behövs någon form av minne ... … enklast möjliga Abstraktionsnivåer Med rätt DS får algoritmen hög abstraktionsnivå blir algoritmen effektiv ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Datastrukturen mängd (eng. Set) Algoritmer och datastrukturer, förel. 1 Datastrukturen mängd (eng. Set) En mängd är en ”oordnad struktur utan duplikat” Operationer add(x) lägg till x till mängden contains(x) finns x i mängden? Axiom: Om x S så S = S {x} Alt. Om S.contains(x) så S == S.add(x) att lägga till ett element flera gånger ger samma resultat som att bara lägga till det en gång String är oxå en datastruktur Repetera matten från åk1 + boolesk algebra Det finns multimängder, påsar, bag Sådana axiom är typiska när man specificerar en datastruktur användarorienterat! Tjänster (”nytta”) vs underliggande teknik ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Exempel på användning av en mängd Algoritmer och datastrukturer, förel. 1 Exempel på användning av en mängd Exempel: Skriv ut en serie inlästa tal utan duplikat m.h.a. en mängd Ex. indata 4 1 3 1 2 1 4 3 skall ge utskriften 4 1 3 2 Informell ”matematisk” algoritm: Utskrivna = Så länge det finns mer indata Läs N Om N Utskrivna Skriv ut N Utskrivna = Utskrivna { N } Är detta samma sak? TAVLAN Om N Utskrivna Skriv ut N Utskrivna = Utskrivna { N } ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Ett Java-gränssnitt för mängder Algoritmer och datastrukturer, förel. 1 Ett Java-gränssnitt för mängder public interface Set { void add(int x); // add an element boolean contains(int x); // is x in the set? } OBS, gränsnittet bevaras i de följande generaliserade versionerna Hur kan man använda klassen utan att veta hur data representeras? ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Algoritmer och datastrukturer, förel. 1 Exemplet i Java (1) Exempel: Skriv ut en serie inlästa tal utan duplikat m.h.a. en mängd Ex. indata 4 1 3 1 2 1 4 3 skall ge utskriften 4 1 3 2 public static void main(String[] args) { Set printed = new SomeImplementingClass(); int n; System.out.print("Skriv in tal:”); while ( more data ) { read an int into n if ( ! ( printed.contains( n ) ) ) { System.out.println( n ); printed.add( n ); } } } Det gick ju bra! Växelspel mellan datastruktur och algoritm: Operationerna (tjänsterna) avgör på vilken abstraktionsnivå algoritmen blir. Hur blir det om man bara känner till fält? Kan man använda String, mja inte generellt ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Mängder av små ickenegativa heltal Algoritmer och datastrukturer, förel. 1 Mängder av små ickenegativa heltal public class SimpleSet implements Set { private // data representation public SimpleSet(int maxNum) {…} // constructor public void add(int x) {…} // add an element public boolean contains(int x) {…} // is x in the set? } OBS, gränsnittet bevaras i de följande generaliserade versionerna Hur kan man använda klassen utan att veta hur data representeras? ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Algoritmer och datastrukturer, förel. 1 Exemplet i Java (2) public static void main(String[] args) { Set printed = new SimpleSet(99); int n; System.out.print("Skriv in POSITIVA TAL < 100:”); while ( more data ) { read an int into n if ( ! ( printed.contains( n ) ) ) { System.out.println( n ); printed.add( n ); } } } Det gick ju bra! Växelspel mellan datastruktur och algoritm: Operationerna (tjänsterna) avgör på vilken abstraktionsnivå algoritmen blir. Hur blir det om man bara känner till fält? Kan man använda String, mja inte generellt ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Algoritmer och datastrukturer, förel. 1 Datarepresentation x [0, maxNum] ... 4 3 2 1 5 6 7 8 maxNum F T 1 T 3 T 7 T 8 T 5 array Fördelar: lätt att addera nya element lätt att testa medlemskap Jobba på två plan: Anv. ----------------------------- Impl. Animera! array[x] == true omm x finns i mängden ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Mängder av små ickenegativa heltal Algoritmer och datastrukturer, förel. 1 Mängder av små ickenegativa heltal public class SimpleSet implements Set { private boolean[] array; // reference to array private int maxNum; // max size of stored number public SimpleSet(int maxNum) {…} // constructor public void add(int x) {…} // add an element public boolean contains(int x) {…} // is x in the set? } ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Algoritmer och datastrukturer, förel. 1 Implementering // constructor public SimpleSet( int maxNum ) { assert ( maxNum > 0 ); array = new boolean[ maxNum + 1 ]; // allocate array this.maxNum = maxNum; for ( int i = 0; i <= maxNum; i++ ) array[ i ] = false; // initialize the array } Man indexerar med elementen assert - exception ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Algoritmer och datastrukturer, förel. 1 ... add och member public void add( int x ) { assert ( x >= 0 && x <= maxNum ); array[ x ] = true; } public boolean contains( int x ) { return array[ x ]; ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Algoritmer och datastrukturer, förel. 1 Begränsningar Elementen kan ej längre vara index i fältet Hur hanterar vi mängder av godtyckliga heltal? flyttal? andra typer? Ny datarepresentation ... 4 3 2 1 Inga duplikat 3 1 8 7 Vad händer om maxNum=109 Man kan inte indexera med flyttal ”position 3.7” ej meningsfullt! Spelar det någon roll om vi lagrar duplikat? Spelar det någon roll vad som lagras i fältet - så länge elementen har samma typ? Varje representation har sina fördelar beroende på tillämpningen Men samma gränssnitt! 5 ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Generalisering i tre steg Algoritmer och datastrukturer, förel. 1 Generalisering i tre steg Klarar små positiva heltal SimpleSet Ny data- representation Klarar godtyckliga heltal Klarar ej flyttal, strängar, ... SetOfInt Klarar alla elementtyper som är jämförbara Generalisera till fler typer Gör klassen generisk! Typiskt ”trade-off”-problem: Metod 1: Snabb, men slösar med minne Metod 2: Sökning behövs vid båda operationerna. Mer minnesekonomisk. 1 <-> 2, typiskt ”trade off”-problem Metod 3: Som 2, men mer generell Samma ADT (gränssnitt) men olika datastrukturer (representation) GenericSet (of anything) ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Mängder av godtyckliga heltal Algoritmer och datastrukturer, förel. 1 Mängder av godtyckliga heltal public class SetOfInt implements Set { private static final int DEFAULT_CAPACITY = 256; private static final int SIZE_INCREMENT = 128; private int capacity = DEFAULT_CAPACITY; // Array capacity private int size = 0; // Number of distinct elements private int[] array = new int[ capacity ]; public void add( int x ) { ... } public boolean contains( int x ) { ... } } Ny datarepresentation (se bild -2) Samma operationer som förut I nästa steg frigör vi oss från begränsningen av elementtypen ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Fältallokering i SetOfInt.add Algoritmer och datastrukturer, förel. 1 Fältallokering i SetOfInt.add 1. fullt! x 3. kopiera elementen 4. addera nya elementet 2. allokera ett större fält Kommentera INTE fältdublering nu, det kommer nästa vecka! ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Algoritmer och datastrukturer, förel. 1 SetOfInt.add Algoritmer och datastrukturer, förel. 1 public void add( int x ) { if ( this.contains(x) ) return; if ( size == capacity ) { // buffer full? int[] old = array; // handle to old array // allocate a bigger array capacity += SIZE_INCREMENT; array = new int[ capacity ]; // copy elements for( int i = 0; i < size; i++ ) array[ i ] = old[ i ]; } // add the new element array[ size++ ] = x; OBS användningen av contains för att testa om elementet redan finns i mängden kan vi tillåta duplikat? Enklare tillägg, men kan kräva mycket minne: tid <-> minne Vi måste kunna jämföra element, annars spelar typen ingen roll ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Algoritmer och datastrukturer, förel. 1 SetOfInt.contains public boolean contains( int x ) { for ( int i = 0; i < size; i++ ) if ( array[ i ] == x ) return true; return false; } Här behövs sökning linjär om fältet är oordnat ordning kräver arbete Vi måste kunna jämföra element med likhet (==), annars spelar typen ingen roll Ordning kräver arbete Förra metoden var just en sorteringsmetod. ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Algoritmer och datastrukturer, förel. 1 Generiska klasser En generisk klass är en klassmall där vissa typnamn ersätts med typvariabler Typvariablerna specificeras i en typparameterlista i början av klassdefinitionen En generisk klass instansieras explicit med konkreta typer i samband med objektdeklarationer. De konkreta typerna ersätter typvariablerna i klassen. … mer nästa gång ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Det generiska gränssnittet GenericSet Algoritmer och datastrukturer, förel. 1 Det generiska gränssnittet GenericSet public interface GenericSet<T> { void add( T x ); boolean contains( T x ); } T är en typvariabel för mängdens element Generalisera mängdklassen. Första ”naiva” försöket ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Klassen GenericArraySet Algoritmer och datastrukturer, förel. 1 Klassen GenericArraySet public class GenericArraySet<T> implements GenericSet<T> { void add( T x ) { ... } boolean contains( T x ) { ... } } En klass som implementerar gränssnittet ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Klassen GenericArraySet Algoritmer och datastrukturer, förel. 1 Klassen GenericArraySet public boolean contains(T x ) { for ( int i = 0; i < setSize; i++ ) if ( array[ i ] == x ) return true; return false; } Duger likhetsoperatorn för Jämförelse av objekt? Skall vi bygga in likhetsoperationen i klassen? implementera Comparable… … eller skicka den operationen som parameter? kan ej skicka metoder men väl objekt Svar: Nä! ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Exempel: Tag bort duplikat ur en ordföljd Algoritmer och datastrukturer, förel. 1 Exempel: Tag bort duplikat ur en ordföljd public static void main(...) { GenericSet<String> printed = new GenericArraySet<String>(); String word; while ( more words ) { read a word if ( ! printed.contains(word)) { System.out.println(word); printed.add( word ); } Vid instansiering av generisk klass måste man ange typen (behövs ej för funktioner) Här instansierar vi en klass (Set) med en annan (String) ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Den generiska klassen GenericArraySet Algoritmer och datastrukturer, förel. 1 Den generiska klassen GenericArraySet public class GenericArraySet<T> implements GenericSet<T> { private static final int DEFAULT_CAPACITY = 256; private static final int SIZE_INCREMENT = 128; private int capacity = DEFAULT_CAPACITY; // Array capacity private int size = 0; // Number of distinct elements *) private T[] array = (T[])new Object[capacity]; public GenericArraySet() { ... } public void add(T x) { ... } public boolean contains(T x) { ... } } *) typvariabler får ej användas för att deklarera fält - använd Objekt och typomvandla ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
GenericArraySet.contains Algoritmer och datastrukturer, förel. 1 GenericArraySet.contains public boolean contains(T x) { for ( int i = 0; i < size; i++ ) if ( x.equals(array[i]) ) return true; return false; } ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4
Algoritmer och datastrukturer, förel. 1 GenericArraySet.add public void add( T x ) { if ( this.contains(x) ) return; if ( size == capacity ) { // buffer full? T[] old = array; // handle to old array // allocate a bigger array capacity += SIZE_INCREMENT; array = (T[])new Object[capacity]; // copy elements for( int i = 0; i < size; i++ ) array[ i ] = old[ i ]; } // add the new element array[size++] = x; ©Uno Holmer, Chalmers, 2019-02-17 03:42 www.cse.chalmers.se/~holmer/ LET375, DAI2+I2, 17/18, lp 4