Föreläsning ALGORITMER: SÖKNING, REGISTRERING, SORTERING

Relevanta dokument
Föreläsning REPETITION & EXTENTA

Föreläsning 3-4 Innehåll

Föreläsning 3-4 Innehåll. Diskutera. Metod. Programexempel med metod

Datastrukturer. Föreläsning Innehåll. Program med vektor Exempel. Deklarera vektorer

Föreläsning 8 SLUMPTAL, SIMULERING + INTRODUKTION TILL VEKTORER

Föreläsning 9-10 Innehåll

Saker du ska kunna Föreläsning 13 & 14

Sortering. Om du följt dessa steg korrekt så ska böckerna nu vara sorterade.

Föreläsning 5 Innehåll

Algoritmer. Två gränssnitt

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

Föreläsning 1 & 2 INTRODUKTION

OOP Objekt-orienterad programmering

Sökning och sortering

EDAA20 Föreläsning Klassen ArrayList. Viktiga operationer på ArrayList. Generisk klass

Programmeringsteknik och Matlab. Dagens program. Viktiga datum. Repetitionsexempel. Repetition av if/else, for, while och Scanner

Föreläsning 5 Innehåll. Val av algoritm och datastruktur. Analys av algoritmer. Tidsåtgång och problemets storlek

Föreläsning 1 & 2 INTRODUKTION

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

OOP Objekt-orienterad programmering

String [] argv. Dagens Agenda. Mer om arrayer. Mer om arrayer forts. String [] argv. argv är variabelnamnet. Arrayer och Strängar fortsättning

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

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

Programexempel: tärningsspel. Programexempel: tärningsspel Kasta tärning tills etta. Klassen Die Specifikation. Slumptalsgenerator Klassen Random

Dagens text. Programmeringsteknik. Mer om Scanner-klassen. Dialogrutor (klassen JOptionPane) Bubbelsortering. Omslagsklasser.

Tentamen i Algoritmer & Datastrukturer i Java

Tentamen, EDA501 Programmering M L TM W K V

Tentamen, EDAA10 Programmering i Java

TENTAMEN OOP

Föreläsning 3: Booleans, if, switch

Tentamen, EDAA20/EDA501 Programmering

Algoritmer och effektivitet. Föreläsning 5 Innehåll. Analys av algoritmer. Analys av algoritmer Tidskomplexitet. Algoritmer och effektivitet

Tentamen DE12, IMIT12, SYST12, ITEK11 (även öppen för övriga)

Outline. For. I istället för att följa det normala ordningen, man ändra den. I i Java får man inte göra hopp hur som helst

Programmering för Språkteknologer II. Innehåll. Associativa datastrukturer. Associativa datastrukturer. Binär sökning.

System.out.println("Jaså du har "+ antalhusdjur+ " husdjur"); if ( antalhusdjur > 5 ) System.out.println("Oj det var många);

Dagens program. Programmeringsteknik och Matlab. Objektorienterad programmering. Vad är vitsen med att ha både metoder och data i objekten?

Föreläsning 11 Datastrukturer (DAT037)

F4. programmeringsteknik och Matlab

Tentamen, EDAA20/EDA501 Programmering

1 Uppgift 1. a) Skapar ett Company-objekt med hjälp av den överlagrade konstruktorn. Du kan själv välja värden på instansvariablerna.

Mer källkod. Styrstrukturer Val Slingor Operatorer Källkodsexempel med minne. Erik Forslin. Rum 1445, plan 4 på Nada

Tentamen, EDA501/EDAA20 Programmering M MD W BK L

Datatyper och kontrollstrukturer. Skansholm: Kapitel 2) De åtta primitiva typerna. Typ Innehåll Defaultvärde Storlek

Dagens text. Programmeringsteknik. Mer om Scanner-klassen. Dialogrutor (klassen JOptionPane) Bubbelsortering. Omslagsklasser.

Tentamen i Algoritmer & Datastrukturer i Java

Del A (obligatorisk för alla)

OOP Tenta

Grundkurs i programmering, 6 hp (725G61) Dugga 2 tillfälle 2

Instuderingsfrågor, del D

Sökning och sortering. Sökning och sortering - definitioner. Sökning i oordnad lista. Sökning med vaktpost i oordnad lista

Sökning och sortering

Tentamen. Datalogi I, grundkurs med Java 10p, 2D4112, Lördagen den 30 november 2002 kl , salar E33, E34

Chapter 4: Writing Classes/ Att skriva egna klasser.

Föreläsning 10 Innehåll. Prioritetsköer och heapar. ADT Prioritetskö. Interface för Prioritetskö. Exempel på vad du ska kunna

Del A (obligatorisk för alla)

Programmering för språkteknologer II. OH-serie: Sökning och sortering. Algoritm

Föreläsning 10 OM DELMÅLSKONTROLLEN ; VARIABLERS SYNLIGHET STRING OCH STRINGBUILDER

Tentamen i Programmeringsteknik I,, KandMa/Fy,

Kompilering och exekvering. Föreläsning 1 Objektorienterad programmering DD1332. En kompilerbar och körbar java-kod. Kompilering och exekvering

Föreläsning 11 Innehåll

Grundläggande programmering, STS 1, VT Sven Sandberg. Föreläsning 12

Sökning i ordnad lista. Sökning och sortering. Sökning med vaktpost i oordnad lista

F5 Selektion och iteration. ID1004 Objektorienterad programmering Fredrik Kilander

Att deklarera och att använda variabler. Föreläsning 10. Synlighetsregler (2) Synlighetsregler (1)

Föreläsning 12 Innehåll

Bedömning av kontrollskrivning, EDA016 Programmeringsteknik

Föreläsning 12 Innehåll

public static void mystery(int n) { if (n > 0){ mystery(n-1); System.out.print(n * 4); mystery(n-1); } }

Logik och Jämförelser. Styrsatser: Villkorssatsen if och repetitonssatsen for. Scriptfiler. Kommentarer. Tillämpningar: Ett enkelt filter.

Objektorienterad programmering i Java

DAT043 Objektorienterad Programmering

Laboration 13, Arrayer och objekt

OOP Tentamen

OOP Tentamen

Objektorienterad programmering. Fält som funktionsresultat. Mer om fält: att uppdatera ett parameterfält. Kontrast: Parametrar av primitiv typ

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

Dagens program. Programmeringsteknik och Matlab. Viktiga datum. Ett första exempel. Programmall, vad behöver vi i ett javaprogram?

OOP Objekt-orienterad programmering

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

Algoritmanalys. Genomsnittligen behövs n/2 jämförelser vilket är proportionellt mot n, vi säger att vi har en O(n) algoritm.

ITK:P1 Föreläsning 1. Programmering. Programmeringsspråket Java. Stark typning Explicit typning Strukturerat Hög säkerhet

Tentamen, EDAA20/EDA501 Programmering

Lösningsförslag till tentamen i EDA011 Programmeringsteknik för F, E, I, π och N

Tentamen, EDAA20/EDA501 Programmering

Dagens föreläsning. Repetition. Repetition - Programmering i C. Repetition - Vad C består av. Repetition Ett första C-program

TDDI16 Datastrukturer och algoritmer. Algoritmanalys

Objekt som argument. Föreläsning 7-8 Innehåll. Hur komma åt den andra kvadratens attribut? Anropa metod på objektet självt

Det finns en referensbok (Java) hos tentavakten som du får gå fram och läsa men inte ta tillbaka till bänken.

Lösningsförslag till tentamen i EDA011, lördagen den 16 december 2006

Objekt-orientering. Java är ett objekt-orienterat programmeringsspråk

Föreläsning 7-8 Innehåll

Tentamen i Programmering

Lösningsförslag till exempeltenta 1

Tentamen i Programmeringsteknik I

Dagens föreläsning. Arrayer och klasser. Medan ni väntar: Gå till m.voto.se/prog11 och svara på några gamla tentamensfrågor! (26 januari 2018 F3 1 )

Tentamen OOP

EDAA20 Programmering och databaser. Mål komprimerat se kursplanen för detaljer. Om att lära sig programmera. Föreläsning 1-2 Innehåll.

Examination i. PROGRAMMERINGSTEKNIK F1/TM1 TIN212 (Dugga) Dag: Onsdag Datum: Tid: (OBS 3 tim) Rum: V

TENTAMEN OOP

Transkript:

Föreläsning 11 12 ALGORITMER: SÖKNING, REGISTRERING, SORTERING

Seminarier: Fredagsklubben för dig som tycker att programmering är svårt (0 eller möjligen 1 poäng på delmålskontrollen) inte avsedda för dem med 2 poäng inte obligatoriska goda erfarenheter från 2016 start på fredag kl 15, därefter (från nästa vecka) fredagar kl 8

Kursadministrativt se kurssidan Labbgrupperna består (men i andra salar se kurssidan!) Kolla i utskicket att du är godkänd på labbar Matlab-komplettering (för F): idag kl 15-17 Lab 6: sköldpadda i labyrint

Sökning Uppgift: Sök upp givet element i en följd av element. Lösning: Gå igenom elementen i tur och ordning, kontrollera för varje element om det är det sökta. Avbryt om det sökta elementet påträffats. Algoritm (linjärsökning) i pseudokod: i = "platsen för det första elementet" while ("fler element kvar att söka igenom" && "elementet på plats i inte är det vi söker") i = platsen för nästa element

Linjärsökning /** Sök efter talet nbr i vektorn v. Om nbr finns returneras platsen för nbr, annars -1 */ public static int indexof(int[] v, int nbr) { int i = 0; while (i < v.length && v[i]!= nbr) { i++; Att fundera på: if (i < v.length) { return i; else { return -1; Varför måste delvillkoret i < v.length stå först? (Läs om short-circuit-evaluering, boken s. 78.) Att fundera på: Varför kan man inte använda villkoret v[i] == nbr för att avgöra om man funnit talet nbr eller ej?

Linjärsökning, snarlik lösning. Men vad är detta? /** Sök efter talet nbr i vektorn v. Om nbr finns returneras platsen för nbr, annars -1 */ public static int indexof(int[] v, int nbr) { int i = 0; while (i < v.length && v[i]!= nbr) { i++; return (i < v.length)? i : -1;

Villkorsuttryck (se kap 6.9 i boken) Värdet av det logiska uttrycket anger vilket av de båda uttrycken som ska beräknas. logiskt uttryck? uttryck 1 : uttryck 2 Beräknas om det logiska uttrycket är sant Detta kan alltid skrivas om med if/else-satser. Beräknas om det logiska uttrycket är falskt Du ska emellertid förstå uttryck av detta slag när du ser dem.

Linjärsökning: kommentar I exemplet på föregående sida förutsätter vi att vektorns alla platser används och ska sökas igenom. Vi har alltså v.length element att söka igenom: while (i < v.length && v[i]!= nbr) I motsvarande exempel i läroboken (avsnitt 8.8) har man en vektor där de bara de n första platserna i vektorn utnyttjas: while (i < n && v[i]!= nbr)

Linjärsökning, en variant till Eftersom metoden inte ska göra något annat än att returnera ett index, så kan man göra det direkt om man vill. /** Sök efter talet nbr i vektorn v. Om nbr finns returneras platsen för nbr, annars -1 */ public static int indexof(int[] v, int nbr) { for (int i = 0; i < v.length; i++) { if (v[i] == nbr) { return i; return -1;

men varning för fel! public static int indexof(int[] v, int nbr) { for (int i = 0; i < v.length; i++) { if (v[i] == nbr) { return i; else { return -1; Varför fungerar inte det här? (Vanligt fel på tentor.)

Exempel: klass för att representera en användare för passerkort User /** Skapar en ny användare med givet kortnummer och namn. */ User(int cardnbr, String name); /** Hämtar användarens kortnummer. */ int getcardnbr(); /** Hämtar användarens namn. */ String getname();

Linjärsökning bland objekt User[] users = new User[100];... // Satser för att skapa 100 User-objekt Uppgift: Sök efter användaren med kortnummer 64319 och skriv ut användarens namn. int i = 0; while (i < 100 && users[i].getcardnbr()!= 64319) { i++; if (i < 100) { System.out.println(users[i].getName());

Varför fungerar inte detta? User[] users = new User[100];... // Satser för att skapa 100 User-objekt Uppgift: Sök efter användaren med kortnummer 64319 och skriv ut användarens namn. int i = 0; while (i < 100 && users[i]!= 64319) { i++; Incompatible operand types User and int if (i < 100) { System.out.println(users[i].getName());

Andra sökalgoritmer Linjärsökning är enkelt, men inte alltid mest effektivt. I en sorterad mängd är binärsökning effektivare. Hur gör du själv när du söker upp ett tal eller ett ord i en sorterad mängd? (Kom ihåg laboration 4.)

Binärsökning: idén Sök upp talet 61 i vektorn v.? v 2 9 22 31 42 56 61 72 76 97? v 2 9 22 31 42 56 61 72 76 97 v 2 9 22 31 42 56 61 72 76 97? v 2 9 22 31 42 56 61 72 76 97!

Binärsökning: formulera algoritmen Sök upp talet 61 i vektorn v. low=0 mid=4 high=9 v 2 9 22 31 42 56 61 72 76 97 Sätt mid = (low + high) / 2 Är v[mid] == 61? Nej, 42 42 < 61, så sätt low = mid + 1 low=5 mid=7 high=9 v 2 9 22 31 42 56 61 72 76 97 Sätt mid = (low + high) / 2 Är v[mid] == 61? Nej, 72 72 > 61, så sätt high = mid 1 mid=5 low=5 high=6 v 2 9 22 31 42 56 61 72 76 97 Sätt mid = (low + high) / 2 Är v[mid] == 61? Nej, 56 56 < 61, så sätt low = mid + 1 mid=6 high=6 low=6 v 2 9 22 31 42 56 61 72 76 97 Sätt mid = (low + high) / 2 Är v[mid] == 61? Ja!

Binärsökning: Java-kod Metoden söker i int-vektorn v efter talet nbr. Returnerar indexet om nbr hittas, annars -1. public static int binarysearch(int[] v, int nbr) { int low = 0; // undre gräns int high = v.length - 1; // övre gräns while (low <= high) { int mid = (low + high) / 2; // mittpunkt if (v[mid] == nbr) { return mid; else if (v[mid] < nbr) { low = mid + 1; else { high = mid - 1; return -1;

Hur lång tid tar sökningen? Anta att vi söker bland N element. Linjärsökning: t ~ N Binärsökning: t ~ log N t k 1 N På den dubbla tiden kan vi linjärsöka 2N element binärsöka N 2 element k 2 log N (Tecknet ~ betyder här proportionellt mot ) N

Registrering Uppgift: Räkna antal element av olika slag. Lösning: Använd en vektor av typ int[] för att lagra de olika antalen. Exempel: Räkna mynt. Vi behöver en låda för enkronor, en för 5- kronor och en för 10-kronor: int[] nbrcoins = new int[3]; enkronor 5-kronor 10-kronor

Exempel: räkna olika tärningsslag Programmet på nästa sida räknar antalet 6:or som en tärning slår. Hur kan man ändra detta till att samla statistik för alla tärningens utfall, det vill säga räkna hur många 1:or, 2:or, 3:or, 4:or, 5:or och 6:or som slås?

Räkna sexor (jämför även lab 7 och exemplet på föreläsning 8) public class DieTest { public static void main(string[] args) { Die d = new Die(); Scanner scan = new Scanner(System.in); System.out.println("Antal tärningskast: "); int nbr = scan.nextint(); int nbr6 = 0; for (int i = 0; i < nbr; i++) { d.roll(); if (d.getresult() == 6) { nbr6++; System.out.println("Det blev en 6:a i " + ((double)nbr6/nbr * 100) + "% av fallen");

Hur spara samtliga tärningsresultat? int[] res = new int[6]; for (int i = 0; i < nbr; i++) { d.roll(); int a = d.getresult(); res[a - 1]++; [0] [1] [2] [3] [4] [5] res 16454 16512 16786 16725 16731 16792 antal 1:or antal 2:or antal 6:or

Exempel: registrera studenters poäng på prov antag att vi har en klass Student: Student /** Tar reda på studentens poäng på provet. */ int getpoints(); (Klassen Student innehåller säkert även en konstruktor och andra metoder vi bortser här från dessa.)

Exempel: registrera studenters poäng på prov public class Test { private Student[] students; // studenterna private int n; // antalet studenter /** Skapar ett prov med plats för max studenter. */ public Test(int max) { students = new Student[max]; n = 0; /** Lägger till studenten s. */ public void add(student s) { students[n] = s; n++; /** Skriver ut antalet studenter som har 0,1,...,50 poäng på provet */ public void printstatistics() {...

Exempel: registrera studenters poäng på prov Antag att vi vill registrera hur många som hade 0, hur många som hade 1, hur många som hade 2 poäng etc. etc. Maxpoäng är 50. public void printstatistics() { int[] nbrs = new int[51]; for (int i = 0; i < n; i++) { int index = students[i].getpoints(); nbrs[index]++; System.out.println("Poäng\tAntal studenter "); for (int i = 0; i < nbrs.length; i++) { System.out.println(i + "\t " + nbrs[i]);

Exempel: registrera studenters poäng på prov Antag att vi vill registrera hur många som hade 0-9 poäng, 10-19 poäng, 20-29 poäng, 30-39 poäng och 40-50 poäng. Detta är ett (nästan) regelbundet intervall och kan därför lösas relativt enkelt. public void printstatistics() { int[] nbrs = new int[5]; for (int i = 0; i < n; i++) { int index = students[i].getpoints() / 10; if (index == 5) { // specialfall: om 50 poäng index = 4; nbrs[index]++; //... skriv ut antalen

Exempel: registrera studenters poäng på prov Tänk istället att 0-24 poäng ger U, 25-34 poäng betyg 3, 35-42 poäng betyg 4 och 43-50 poäng betyg 5. Då har vi ett oregelbundet intervall som vi får hantera annorlunda. Antalet U-betyg registreras i nbrs[0], antalet 3-betyg i nbrs[1], osv. int[] nbrs = new int[4]; // plats för U, 3, 4, 5 //För varje student int points = students[i].getpoints(); int index; if (points < 25) { index = 0; else if (points < 35) { index = 1; else if (points < 43) { index = 2; else { index = 3; nbrs[index]++;

Sortering Lunds Tekniska Högskola Xxxxxxxxxxxxxxxx Xxxxxxxxxxxxxx ÅÅÅÅ-MM-DD

På tentan förväntas du kunna (bland annat) Söka i en vektor eller lista (linjärsökning OK; om vi vill ha t ex binärsökning får du ledtrådar) Registrering Sortering av osorterad vektor eller lista (valfri algoritm; om en viss algoritm behövs får du ledtrådar) Här visas urvalssortering och (något om) bubbelsortering (Senare visas även insättningssortering.)

Urvalssortering: idén Sortera vektorn v. 4 v 2 9 22 31 97 76 72 61 56 42

Urvalssortering (selection sort) Urvalssortering beskrivs i boken (avsnitt 8.9). Princip: Börja på första elementet. Hitta det minsta elementet i resten av listan; byt plats på det minsta och det första. Det första elementet är nu klart. Fortsätt till det andra. Hitta det minsta elementet i återstoden av listan; byt plats på det minsta och det andra. De första två elementen är nu klara. Fortsätt till det tredje. Osv.

Urvalssortering: Java-kod public static void selectionsort(int[] a) { for (int i = 0; i < a.length - 1; i++) { // hitta det minsta elementet efter a[i] for (int k = i + 1; k < a.length; k++) { if (a[k] < a[i]) { int temp = a[i]; // byt värde på a[i] och a[k] a[i] = a[k]; a[k] = temp; i k

Urvalssortering (en lite annan variant) (Per Holm 2007, s. 135. Något modifierad.) public static void selectionsort(int[] a) { for (int i = 0; i < a.length - 1; i++) { int min = Integer.MAX_VALUE; int minindex = -1; for (int k = i; k < a.length; k++) { if (a[k] < min) { min = a[k]; minindex = k; a[minindex] = a[i]; a[i] = min;

Hur lång tid tar urvalssortering? Anta att vi har N element Låt J vara antalet jämförelser av vektorelement Då är J = (N-1) + (N-2) +... + 1 = N(N-1)/2 N 2 /2 Tiden ökar väsentligen kvadratiskt: dubbelt antal element ger fyrdubbel exekveringstid Effektivare sorteringsalgoritmer (N log N) möter ni i EDAA01 Programmeringsteknik fördjupningskurs

En annan enkel sorteringsalgoritm: Bubbelsortering Gå igenom elementen, och jämför alla par av närliggande element (dvs i och i+1, för 0 i < N 1). Om de båda jämförda värdena inte är i ordning, byt plats på dem. Det största elementet bubblar på så vis till den sista platsen. Upprepa alltsammans igen, så att det näst sista elementet får rätt värde, det näst näst sista, och så vidare. Två strategier: Upprepa ovanstående N-1 gånger Upprepa ovanstående tills ingen förändring längre sker Det finns många sätt att göra bubbelsortering

Switch-satsen Lunds Tekniska Högskola Xxxxxxxxxxxxxxxx Xxxxxxxxxxxxxx ÅÅÅÅ-MM-DD

Exempel antal dagar Skriv en sats som givet ett månadsnummer beräknar antal dagar i månaden. Vi bortser från skottår. Scanner scan = new Scanner(System.in); int monthnbr = scan.nextint(); // månadens nummer (1..12) int nbrofdays; // antal dagar if (monthnbr == 2) { nbrofdays = 28; else if (monthnbr==4 monthnbr==6 monthnbr==9 monthnbr==11) { nbrofdays = 30; else { nbrofdays = 31;

Antal dagar switch-sats Scanner scan = new Scanner(System.in); int monthnbr = scan.nextint(); //månadens nummer (1..12) int nbrofdays; // antal dagar switch (monthnbr) { case 2: nbrofdays = 28; break; case 4: case 6: case 9: case 11: nbrofdays = 30; break; default: nbrofdays = 31; break;

Viktigt om switch-case Ersätter upprepande enklare if..else if..else if.. Värdet som testas kan vara av typen byte, short, int, char eller String. Utan break exekveras nästa alternativ också: vid break avbryts hela switch-satsen. Ett vanligt misstag i switch-satser är att glömma break. default är det som körs om inga andra alternativ matchar.

Typisk användning av switch-sats Scanner scan = new Scanner(System.in); System.out.println( Ange kommando (1-3): ); int cmd = scan.nextint(); switch (cmd){ case 1: //Satser för att utföra kommando 1 break; case 2: //Satser för att utföra kommando 2 break; case 3: //Satser för att utföra kommando 3 break; default: System.out.println("Inget giltigt kommando"); break;