Tentamen Programmeringsteknik II 2018-10-19 Skrivtid: 8:00 13:00 Tänk på följande Skriv läsligt. Använd inte rödpenna. Skriv bara på framsidan av varje papper. Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper Fyll i försättssidan fullständigt. Såvida inget annat anges, både får och ska man bygga på lösningar på föregående uppgifter även om dessa inte har lösts. På B-delen är det tillåtet att införa hjälpmetoder och hjälpklasser. Uttrycket skriv en metod som skall alltså inte tolkas så att lösningen inte får struktureras med hjälp av flera metoder. Du behöver inte skriva import-satser för klasserna Scanner, ArrayList, Locale och inte heller för klasser i java.io. All given kod följer kursens kodningsregler. Alla uppgifter gäller programmeringsspråket Java och programkod skall skrivas i Java. Koden skall vara läslig dvs den skall vara vettigt strukturerad och indenterad. Namn på variabler, metoder, klasser etc skall vara beskrivande men kan ändå hållas ganska korta. Observera att betyget påverkas negativt av icke-privata eller onödiga instansvariabler, dålig läslighet, upprepning av identisk kod, underlåtenhet att utnyttja given eller egen tidigare skriven metod. Skrivningen består av två delar. Lösningarna till uppgifterna på A-delen ska skrivas in i de tomma rutorna och den delen ska lämnas in. Rutorna är tilltagna i storlek så att de ska rymma svaren. En stor ruta betyder inte att svaret måste vara stort! Lösningarna till uppgifterna på B-delen skrivs på lösa papper. För att bli godkänd (betyg 3) krävs att minst ca 75% av A-delen är i stort sett rätt löst. För betyget 4 krävs dessutom att minst hälften av uppgifterna på B-delen och betyg 5 att alla uppgifterna på B-delen är i stort sett rätt lösta. Vi bedömning av betyg 4 och 5 tas också hänsyn till kvalitén på lösningarna i A-delen. Observera att B-delen inte rättas om inte A-delen är godkänd. Lycka till!
Inledning I bilagor finns ett antal mer eller mindre ofullständiga klasser. Klassen List innehåller några grundläggande komponenter för att skapa och hantera enkellänkade listor av heltal. Listorna hålls inte sorterade och ett tal kan förekomma flera gånger. Klassen ListSet är en subklass till List. Dessa listor hålls sorterade i storleksordning med det minsta talet först och varje tal förekommer högst en gång (inga dubbletter alltså). Klassen BST innehåller binära sökträd med heltal som nycklar. En nyckel kan förekomma högst en gång i trädet. Alla klasser innehåller main-metoder med utskrifter som demonstrerar metoderna. Del A (obligatorisk för alla) A1. Skriv undantagsklassen ExamException som en underklass till RuntimeException. Det skall gå att kasta undantag till exempel på följande sätt: if (i < 0) { throw new ExamException("Illegal index value"); } A2. Skriv metoden public void addfirst(int data) i klassen List som lägger in en ny nod med värdet data först i listan.
A3. Skriv klart den rekursiva hjälpmetoden till copy-metoden i klassen List: public List copy() { return new List(copy(first)); } protected static Node copy(node n) { } A4. Skriv färdigt metoden toarraylist nedan. Metoden ska lägga in alla tal från listan i en arraylist och de ska ligga i samma ordning som i listan. Metoden ska vara iterativ och komplexiteten O(n) där n är antalet element i listan. public ArrayList<Integer> toarraylist() { ArrayList<Integer> result = new ArrayList<Integer>(); } return result;
A5. Skriv metoden int smallest() (inklusive eventuella hjälpmetoder) i klassen List som beräknar och returnerar det minsta värdet lagrat i listan. Välj själv mellan iterativ och rekursiv implementation! A6. Vad blir den interna väglängden i det träd som genereras av nedanstående kodsekvens? (Titta på den givna metoden ipl om du glömt hur begreppet intern väglängd definieras!) BST bst = new BST(); bst.add(10); bst.add(5); bst.add(1); bst.add(17); bst.add(10); bst.add(6); bst.add(4); bst.add(3);
A7. Vad är den minsta möjliga väglängden för ett träd med 7 noder? Motivera! A8. Antag att cirka 1 000 000 olika slumptal matas in i ett binärt sökträd. Ungefär hur många jämförelser bör det i genomsnitt krävas för att återfinna ett lagrat tal? Motivera svaret! Tips: 10 6 2 20
A9. I subklassen ListSet till klassen List ska listorna vara sorterade och dessutom får varje värde förekomma högst en gång. Dessa listor byggs upp med metoden add (se bilagan). En av metoderna i klassen List får inte användas på subklassen ListSet. Vilken och varför? Hur förhindrar man att den obemärkt används? A10. Två metoder som är definierade i klassen List fungerar visserligen fortfarande för ListSet men bör av effektivitetsskäl ändå omdefinieras. Vilka? Vad har de för komplexitet om de inte omdefinieras? A11. Välj en av de metoderna från ovanstående uppgift (lämpligen den enklaste den svårare får du göra i B-delen) och skriv den. Vad är dess komplexitet?
A12. I den första programmeringskursen gjordes paddorna rörliga genom att man hade en loop som dels innehöll en flyttning och omritning av paddorna och dels ett anrop till Thread.sleep(). Nackdelen med detta är att programmet är låst när det sover. I denna kurs har vi använt en annan teknik för att göra rörliga figurer. Beskriv kortfattat (rutan ska inte fyllas med text) denna teknik! Vilka de är de viktiga programdelarna?
Del B (för betyg 4 och 5) Svaren skrivs på lösa papper med ny uppgift på nytt papper. B1. Skriv en rekursiv metod static int noof(int x) som räknar antalet udda siffror i talet x (betraktat som ett decimalt heltal). Exempel: noof(12345) ska bli 3 (siffrorna 1, 3 och 5), noof(3050) ska bli 2 och noof(400004) ska bli 0. Du kan förutsätta att talet inte är negativt. B2. Givet tre olika algoritmer för att lösa ett givet problem. Algoritm A har komplexiteten Θ(n), algoritm B har komplexiteten Θ(n log n) och algoritm C har komplexiteten Θ(n 2 ). För n = 100 har mätningar visat att algoritm A tar 1000 sekunder, algoritm B tar 100 sekunder och algoritm C tar 10 sekunder. a) För vilket värde på n kan vi vänta oss att algoritm A blir snabbare än algoritm B? b) För vilket värde på n kan vi vänta oss att algoritm A i blir snabbare än algoritm C? c) För vilket värde på n kan vi vänta oss att algoritm B i blir snabbare än algoritm C? Här räcker det med att ange första 10-potens som gör att B snabbare än C (alltså 10 3, 10 4, 10 5,... ) Svaren ska motiveras! B3. I klassen List finns en metod atindex(int index) som returnerar värdet lagrat i angiven position. Om index-värdet är mindre än 0 eller större än eller lika med antalet element i listan kastas ett undantag. Se körexemplet! Tyvärr får användaren inte veta värdet på det felaktiga indexet. Som synes i körexemplet blir utskriften: *** Error *** nonexisting index Modifiera koden (huvudmetoden och/eller hjälpmetoden) så att även värdet inkluderas i felmeddelandet! Utskriften ska således bli: *** Error *** nonexisting index: 35 Beräkningarna ska fortfarande göras på samma rekursiva sätt och du får inte ändra i parameterlistorna! B4. Skriv metoden contains(listset s) i klassen ListSet som returnerar true om alla element i listan s också finns i den egna listan. Se körexemplet! Obs: Metodens komplexitet ska vara O(n + m) där n och m är antalet element i den egna listan respektive listan s B5. Skriv en metod boolean contains(bst bst) i klassen BST som returnerar true om alla värden i trädet bst också finns med i det egna trädet, annars false. Metodens komplexitet ska vara O(n + m) där n och m är antalet noder i respektive träd. B6. Implementera den andra (den svårare) av de två metoder som man bör omdefiniera i subklassen ListSet. Hur blir komplexiteten för denna implementation?