TDDC30 Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 7 Jonas Lindgren, Institutionen för Datavetenskap, LiU På denna föreläsning: Bubblesort, Shakersort, Mergesort Strömmar, Datum, Formatering 1
Hittills, och vidare! Objektorientering och Java Objekt, klasser, instanser Arv, polymorfism Dölj implementationen Private/Public (inkapsling) Abstrakta datatyper (ADT) Datastruktur med algoritmer Listor, köer och stackar Gränssnitt vs implementation Analys av algoritmer 100 Komplexitet: tids-, rums- 50 Fallstudie: Sorteringsalgoritmer 2 0 0 10 20
Bubblesort Jämför med närliggande element Start från höga index void bubblesort(int[] a) { for (int i = 0; i < a.length; ++i) { for (int j = a.length-1; j > i; --j){ if (a[j] < a[j-1]) { byt plats på a[j] och a[j-1]; Asymptotisk (tids)komplexitet? Stabil? O(n 2 ) Ja Låg overhead n n 2 3
Shakersort Tvåvägs bubblesort Små element bubblar upp Stora element sjunker ner Fram och tillbaka Jämför med närliggande element Bubbla ner eller bubbla upp Gör om för varje element O(n) O(n) T shakersort? Stabil? O(n 2 ) Ja 4
Kort om rekursion Ibland när man delar upp ett problem, uppstår samma problem igen! T.ex. N! = 1 * 2 * 3 * kan även skrivas: N! = 1 då N = 0, N * (N-1)! annars I java kan en metod anropa sig själv! int fak(int N) { N : 2 if (N == 0) { return 1; return N * fak(n-1) 2 = 2 * 1 svar = fak(2); int fak(int N) { N : 1 if (N == 0) { return 1; return N * fak(n-1) 1 = 1 * 1 int fak(int N) { N : 0 if (N == 0) { return 1; return N * fak(n-1) 5
Divide and Conquer (sv. söndra och härska) En rekursiv strategi: 1. Om datamängden är liten, lös direkt (härska). 2. Annars: dela upp datamängden (söndra) och applicera söndra och härska (rekursivt) på varje del. 3. Sammanfoga lösningarna för varje del till lösningen för hela. 6
Mergesort Strategi: Divide and conquer : Tag två sorterade delmängder och sortera ihop dessa. Algoritm: Då mängden innehåller 0 eller 1 element: Redan sorterad => Klart! Annars: Dela upp mängden i två lika stora delar och sortera dessa Med mergesort! (rekursion) Sortera ihop dessa två delar (en. Merge) 7
Mergesort(2) Utnyttjar att det krävs få jämförelser att sortera små mängder Vanlig optimering: Byt ut sorteringsalgoritmen när delmängden är tillräckligt liten! Komplexitet: Antal uppdelningar av arrayen Mergar på varje nivå O(log(n)) O(n) T mergesort = O(log(n)) * O(n) = O(nlog(n)) R mergesort = O(n) (O(1) möjlig men impl. ger dålig prestanda) Stabil? Ja (om sammanslagningsalgoritmen är väl vald) 8
Sammanfattning Kvadratiska algoritmer Insertionsort Selectionsort Bubblesort Shakersort Mer avancerade algoritmer Shellsort Mergesort Quicksort Enkla, långsamma Komplexa, snabba 9
In- och utmatning Definition: En ström (en. Stream) är en sekvens av data från någon källa och/eller till något mål. In och utmating i Java utförs av strömmar Vanliga exempel System.out (av klassen PrintStream) Vanligen kopplad till terminalen System.err (av klassen PrintStream) Vanligen kopplad till terminalen System.in (av klassen InputStream) Vanligen ihopkopplad med annan ström som formaterar indatat, ex. BufferedReader, BufferedLineReader, Scanner 10
In- och utmatning(2) Exempel // connect reader to inputstream BufferedReader input = new BufferedReader( new InputStreamReader(System.in)); // read a line and convert to int int num = Integer.parseInt(input.readLine()); // open file for reading FileInputStream stream = new FileInputStream( new File("test.txt")); Scanner scanner = new Scanner(stream); // read from file System.out.println(scanner.nextInt()); 11
Formatering Ofta vill man skriva ut på en viss form double d = 10.0/3.0; System.out.println(d); // 3.3333333333333335 Metoden format i PrintStream kan hjälpa till: System.out.format("Värdet %1.2f är bra grejor.\n", d); // 3,33 Locale.setDefault(Locale.UK); // format adjust itself by looking at default locale! System.out.format("The value %1.2f is indeed good\n.", d); // 3.33 12
Formatering(2) Formatspecificerare är på följande form: %[flagga][bredd]typ Typ Förklaring Flaggor Förklaring d Heltal, decimal form - Vänsterjustering x Heltal, hexadecimal form + Talets tecken skrivs ut f Reellt tal, decimalform blankt Positivt tal inleder med blank e Reellt tal, exponentform, Siffrorna grupperas tre och tre 13 Fler specificerare finns, se Javas API-dokumentation
Datum och tid Klassen Date sparar en tid // num = number of milliseconds since Jan 1, 1970 Date date = new Date(num); Klassen Calendar är mer användbar, och kan ta fram nuvarande tid som ett Date. Calendar cal = Calendar.getInstance(); System.out.format("The time is: %tc \n", cal.gettime()); int minute = cal.get(calendar.minute); 14
Datum och tid(2) DateFormat: en (abstrakt) klass som formaterar datum åt oss DateFormat time = DateFormat.getTimeInstance(); DateFormat date = DateFormat.getDateInstance(); Date now = Calendar.getInstance().getTime(); // note that this is locale dependent System.out.println(time.format(now)); // 13:37:00 System.out.println(date.format(now)); // 2012-nov-14 (Mer kontroll? SimpleDateFormat!) 15
Scanner Scanner: En klass som hjälper oss att hantera inmatning Kopplas mot en InputStream // example usage of scanner Scanner keyboard = new Scanner(System.in); while (keyboard.hasnextint()) { mylist.add(keyboard.nextint()); 16
Hantering av strömmar Filer läses som strömmar För textfiler, använd FileReader resp. FileWriter String filename = "myfile.txt"; FileReader reader = new FileReader(new File(filename)); Scanner scanner = new Scanner(reader); //... scanner.close(); // always close your streams! scanner.nextint(); // error, since scanner + stream is now closed 17
Hantering av (binära) datafiler För binära filer, använd DataInputStream resp. DataOutputStream String filename = "myfile.dat"; DataInputStream input; try { input = new DataInputStream(new FileInputStream(filename)); while (true) { System.out.println(input.readInt()); catch (EOFException e) { System.out.println("Something went wrong while reading:"); e.printstacktrace(); // print the details! finally { input.close(); // always close! 18
Serialisering Det går att spara objekt på fil mellan körningar Java kan platta till ett objekt till en sekvens av bytes Perfekt för att spara Använd strömmarna ObjectInputStream och ObjectOutputStream Kräver att klassen implementerar interfacet Serializable Object readobject(); // casting is needed to be usable void writeobject(object o); ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream(new File("test.dat"))); out.writeobject(new Cat("Isaac", 11)); // if Serializable! out.writeobject("hejsan"); // String is Serializable 19