Introduktion Föreläsning (Weiss kap. -4) Många begrepp blir det Introduktion till kursen Exempel: Datastrukturen mängd Generiska<klasser> Den som bara har en hammare tror att alla problem är spikar Vilken loop är snabbast? for ( i = 0; i < n; i++ ) for ( j = 0; j < n; j++ ) // massa jobb... for ( i = 0; i < n; i++ ) for ( j = i; j < n; j++ ) // massa jobb... Uno Holmer, Chalmers, 09-03- 4:46 3 4 Vad kan man ha en datastruktur till? Datastrukturen mängd (eng. Set) Problem: Skriv ut en serie inlästa tal utan duplikat Ex. indata 4 3 4 3 skall ge utskriften 4 3 det behövs Informell algoritm: någon form av minne... Så länge det finns mer indata Läs N Om N ej är utskrivet tidigare Skriv ut N enklast möjliga Kom ihåg N 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 6
Exempel på användning av en mängd Ett Java-gränssnitt för mängder Exempel: Skriv ut en serie inlästa tal utan duplikat m.h.a. en mängd Ex. indata 4 3 4 3 skall ge utskriften 4 3 Informell matematisk algoritm: Utskrivna = Så länge det finns mer indata Läs N Om N Utskrivna Skriv ut N Utskrivna = Utskrivna N public interface Set void add(int x); boolean contains(int x); // is x in the set? 7 8 Exempel: Exemplet i Java () Skriv ut en serie inlästa tal utan duplikat m.h.a. en mängd Ex. indata 4 3 4 3 skall ge utskriften 4 3 Mängder av små ickenegativa heltal 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 ); public class SimpleSet implements Set private // data representation public SimpleSet(int maxnum) // constructor public void add(int x) public boolean contains(int x) // is x in the set? 9 0 Exemplet i Java () public static void main(string[] args) Set printed = new SimpleSet(99); int n; System.out.print("Skriv in POSITIVA TAL < 00: ); while ( more data ) read an int into n if (! ( printed.contains( n ) ) ) System.out.println( n ); printed.add( n ); Datarepresentation x [0, maxnum] 3 7 8 array F TF F TF F TF F TF TF... F 0 3 4 6 7 8... maxnum array[x] == true omm x finns i mängden
Mängder av små ickenegativa heltal Implementering 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) public boolean contains(int x) // is x in the set? // constructor public SimpleSet( int maxnum ) assert ( maxnum > 0 ); array = new boolean[ maxnum + ]; // allocate array this.maxnum = maxnum; for ( int i = 0; i <= maxnum; i++ ) array[ i ] = false; // initialize the array 3 4... add och member public void add( int x ) assert ( x >= 0 && x <= maxnum ); array[ x ] = true; Begränsningar Hur hanterar vi mängder av godtyckliga heltal? flyttal? andra typer? Elementen kan ej längre vara index i fältet public boolean contains( int x ) assert ( x >= 0 && x <= maxnum ); return array[ x ]; 3 7 8 3 0 8 7... 3 4... Inga duplikat 6 Generalisering i tre steg Mängder av godtyckliga heltal Klarar små positiva heltal SimpleSet (se bild -) Klarar godtyckliga heltal SetOfInt Klarar ej flyttal, strängar,... public class SetOfInt implements Set private static final int DEFAULT_CAPACITY = 6; private static final int SIZE_INCREMENT = 8; private int capacity = DEFAULT_CAPACITY; // Array capacity private int size = 0; // Number of distinct elements private int[] array = new int[ capacity ]; Klarar alla elementtyper som är jämförbara Generalisera till fler typer GenericSet (of anything) Gör klassen generisk! public void add( int x )... public boolean contains( int x )... Samma operationer som förut 7 8 3
Fältallokering i SetOfInt.add. fullt! 3. kopiera elementen 4. addera nya elementet x. allokera ett större fält SetOfInt.add 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; 9 0 SetOfInt.contains public boolean contains( int x ) for ( int i = 0; i < size; i++ ) if ( array[ i ] == x ) 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. Det generiska gränssnittet GenericSet Klassen GenericArraySet public interface GenericSet<T> void add( T x ); boolean contains( T x ); T är en typvariabel för mängdens element public class GenericArraySet<T> implements GenericSet<T> void add( T x )... boolean contains( T x )... 3 4 4
Klassen GenericArraySet Exempel: Tag bort duplikat ur en ordföljd public boolean contains(t x ) for ( int i = 0; i < setsize; i++ ) public static void main(...) GenericSet<String> printed = new GenericArraySet<String>(); if ( array[ i ] == x ) Duger likhetsoperatorn för Jämförelse av objekt? Svar: Nä! String word; while ( more words ) read a word if (! printed.contains(word)) System.out.println(word); printed.add( word ); 6 Den generiska klassen GenericArraySet public class GenericArraySet<T> implements GenericSet<T> private static final int DEFAULT_CAPACITY = 6; private static final int SIZE_INCREMENT = 8; 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 GenericArraySet.contains public boolean contains(t x) for ( int i = 0; i < size; i++ ) if ( x.equals(array[i]) ) 7 8 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; 9