Facit Tentamen TDDC30 2013-06-05 1 (6) Teoretisk del 1. (3p) "Snabba frågor" Alla svar motiveras väl. a) Vad skiljer en statisk metod från en icke-statisk? (0.5p) Svar:En statisk metod är associerad till klassen, och kan anropas utan en instans av klassen. En icke-statisk metod är å andra sidan associerad med en viss instans av klassen, och kan bara anropas via en sådan instans. Den icke-statiska metoden har då tillgång till den instansens instansvariabler, till skillnad från den statiska metoden som endast har tillgång till klassvariabler. b) Vad är syftet med ett interface? (0.5p) Svar:Att ange vilka metoder som ska finnas, utan att behöva ange hur de ska vara implementerade eller vilken basklass klassen ska ärva av. c) Klasser kan placeras i paket. Varför gör man det? (0.5p) Svar:För att organisera relaterade klasser i en sammanhängande, logisk struktur. För att kunna importera en klass från klasser i andra paket måste även den klassen som ska importeras ligga i ett paket. För synlighet spelar paket också roll, då package private eller protected ger synlighet inom samma paket, men ej för klasser i andra paket. d) Vad är syftet med en konstruktor? (0.5p) Svar:Att säkerställa att instanser av klasser byggs på rätt sätt, t.ex. att alla variabler initieras korrekt och för att kontrollera att alla värden som skickas in som parametrar till konstruktorn har korrekta värden. e) Vad innebär det att en algoritm har tidskomplexiteten O(n)? (0.5p) Svar:Tidskomplexitet O(n) innebär att den tid algoritmen tar i sitt värsta fall, är linjärt beroende av storleken på indata. f) I Car mycar = new Car() sker två separata saker. Vad innebär Car mycar och vad innebär new Car()? (0.5p) Svar: Car mycar skapar en variabel som är en referens till ett Car-objekt, men skapar inte det tillhörande Car-objektet. new Car() skapar ett Car-objekt, som det måste lagras en referens till i någon slags variabel för att den ska forsätta existera.
Facit Tentamen TDDC30 2013-06-05 2 (6) 2. (3p) "Datastrukturer" För dessa tre separata binära träd: I 0 II 7 III 4 1 2 9 6 8 3 5 a) Ange vilka av dessa träd, om några, som är: (1p) 1) Fulla Svar:I och II. 2) Perfekta Svar:II. 3) Fullständiga Svar:II och III. b) Ange i vilken ordning värdena skulle skrivas ut genom en postorder-traversering för vart och ett av dessa träd. (0.5p) Svar:I: 1 8 3 2 0 II: 7 III: 5 9 6 4 c) Organisera värdena [ 0 1 2 3 4 5 6 7 8 9 ] i en binär maxheap av minimalt djup. Visa med en bild. (0.5p) Svar: (flera möjliga svar finns) 9 8 7 6 5 4 3 2 1 0 d) Organisera valfritt antal av värdena [ 0 1 2 3 4 5 6 7 8 9 ] i ett fullt binärt sökträd av så stort djup som möjligt. Visa med en bild. (1p) Svar: (flera möjliga svar finns) 1 2 4 3 6 5 8 7 9
Facit Tentamen TDDC30 2013-06-05 3 (6) 3. (3p) "Tidskomplexitet" a) Förenkla följande tre uttryck för tidskomplexitet: (1p) * O(n) O(3n) + O(5n) Svar:O(n 2 ) * O(3n 2 + n) Svar:O(n 2 ) * O(2n) + O(5 + 4n) Svar:O(n) b) Ange tidskomplexiteten i värsta fallet, med avseende på n, för följande två metoder. (n är alltid ett positivt heltal) (2p) Svar: void foo(int n) { // O(5) * O(2n) * O(1) => O(n) for (int i = 0; i < 5; i = i + 1) { // O(5) for (int j = 0; j < 2*n; j = j + 1) { // O(2n) System.out.println("foo: "+i+" x "+j+": "+(i*j)); // O(1) void bar(int n) { // O(n) * O(log(n)) => O(n*log(n)) System.out.println("bar: " + n); // O(1) if (n!= 0) { // O(1) foo(n); // O(n) bar(n/2); // rekursionen ger O(log(n)), se nedan // Rekursiva metoder är knepiga, men rekursion brukar // kunna "översättas" till någon slags loop. I det här // fallet är bar ovan ekvivalent till bar_iterativ här // nedan, och ur den iterativa metoden kan vi lätt // utläsa tidskomplexiteten void bar_iterativ(int n) { // O(log(n)) * (O(n) + O(1)) => O(n*log(n)) for (int i = n; i > 0; i = i / 2) { // O(log(n)) System.out.println("bar: " + n); // O(1) foo(n); // O(n)
Facit Tentamen TDDC30 2013-06-05 4 (6) 4. (3p) "Algoritmer" a) Sortera värdena [ 1 5 2 6 7 2 4 ] med shellsort med lucksekvensen [ 3 2 1 ]. Gör detta genom att byta plats på värden inom fältet, dvs. in-place. Sorteringen ska leda till stigande ordning, dvs 1, 2, 3, osv. Ange tydligt i svaret hur fältet ser ut innan varje platsbyte, samt vilka index som är på väg att byta plats, med maximalt ett byte per steg. (1p) Svar:Luckvärde 3 [ 1 5 2 6 7 2 4 ] Luckvärde 2 [ 1 5 2 4 7 2 6 ] [ 1 5 2 4 6 2 7 ] [ 1 4 2 5 6 2 7 ] [ 1 4 2 2 6 5 7 ] Luckvärde 1 [ 1 2 2 4 6 5 7 ] [ 1 2 2 4 5 6 7 ] b) Sortera värdena [ 2 5 2 6 7 1 4 ] med selectionsort. Gör detta genom att byta plats på värden inom fältet, dvs. in-place. Sorteringen ska leda till stigande ordning, dvs 1, 2, 3, osv. Ange tydligt i svaret hur fältet ser ut innan varje platsbyte, samt vilka index som är på väg att byta plats, med maximalt ett byte per steg. (1p) Svar:[ 2 5 2 6 7 1 4 ] [ 1 5 2 6 7 2 4 ] [ 1 2 5 6 7 2 4 ] [ 1 2 2 6 7 5 4 ] [ 1 2 2 4 7 5 6 ] [ 1 2 2 4 5 7 6 ] [ 1 2 2 4 5 6 7 ] c) Kan de två sorteringsalgoritmerna ovan implementeras stabila? Ange separat svar för varje algoritm, samt motivera varför. (1p) Svar:Shellsort är ej stabil då luckvärdet ger upphov till att värden av samma storlek som ligger inom olika luck-grupper kan hoppa över varandra och byta plats relativt varandra. Exempel: Luckvärde 2, [ 2 2 1 6 7 2 4 ] Selectionsort är ej stabil då det utvalda minsta osorterade värdet, vart det än ligger, byter plats med det värde som råkar ligga där det minsta värdet ska placeras. Det kan leda till att ett värde hoppar över ett annat värde av samma storlek, pga. det minsta osorterade värdet ligger till höger om det andra värdet av samma storlek. Exempel: [ 2 3 2 6 7 1 4 ]
Facit Tentamen TDDC30 2013-06-05 5 (6) 5. (4p) Ko-Klassikern Stefan har fått besked att en av hans fjärran släktingar har avlidit, och lämnat sin gård till Stefan. Om man bortser från dödsfallet så är detta goda nyheter för Stefan, då han på senare tid fått blodad tand för livet på landet! På gården ska det tydligen finnas ett antal nötkreatur, och Stefans dröm om ett stadigt förråd av färska mjölkprodukter kan till slut bli en realitet! Dock finns det ett problem, Stefan har lite problem med att hålla isär alla dessa olika sorters nötkreatur. Kor, tjurar och kalvar, vad är skillnaden egentligen, hur mycket väger de och viktigast av allt, hur mycket mjölk producerar de? För att reda ut skillnaderna har Stefan bestämt sig för att skriva ett enkelt program, där han för varje djur kan få reda på dess namn, en uppskattning av dess vikt och en uppskattning av dess mjölkproduktion. a) Hjälp Stefan skriva klart sitt program. Det ska finnas minst fyra klasser, Animal, Cow, Bull och Calf. Fler klasser är tillåtna. Varje klass ska det sedan gå att köra ett antal metoder på, som ska returnera namn, vikt och mjölkproduktion, respektive. (2p) (Se på hur klasserna används i testprogrammet, det demonstrerar vad rätt svar från programkörningen ska vara. Testprogrammet ska fungera utan ändringar, dock får ni gärna göra egna testprogram.) b) Som en fortsättning på del a vill Stefan lösa problemet med så få metoder som möjligt. Han har funderat på saken, och kommit fram till att det borde inte behövas mer än 5 get-metoder, totalt, bland alla klasser. För att det ska bli lite utmaning kräver Stefan att detta löses utan några som helst klass- eller instans-variabler, förutom name i Animal. (2p) (Förtydling: getname() i Animal räknas ej med bland dessa 5 get-metoder, endast de ni själva lägger till räknas.)
Facit Tentamen TDDC30 2013-06-05 6 (6) 6. (5p) Den Prioriterade Semestern Anna planerar sin semester för sommaren men det finns så många intressanta resemål att besöka, och hon är inte riktigt säker på vad som är den rätta destinationen för henne. För att underlätta sin planering har hon bestämt sig för att göra en prioritetskö av de hetaste kandidaterna. Dock har hon några tentor som hon också måste plugga och gå upp på, så hon har inte riktigt hunnit skriva klart sin kod. a) Hjälp Anna skriva klart, genom att färdigställa hennes remove-metod. Annas prioritetskö är implementerad som en maxheap som i sin tur lagras i ett fält (I det här fallet en ArrayList). Remove-metoden ska returnera och ta bort det största värdet i prioritetskön, som alltså ligger överst i heapen. Om man ska ta bort det översta värdet och fortfarande ha en korrekt maxheap måste man som bekant flytta upp värdet längst nere till höger i heap-strukturen till toppen, och sedan bubbla ner den till rätt plats. Detta sker genom att man byter plats med den nya noden och dess största barn, och sedan upprepar proceduren tills noden som bubblas ligger på rätt plats. (4p) (Kom ihåg att se till att remove fungerar väl i alla fall, även de som kanske inte testas av det givna testprogrammet. Testprogrammet ska fungera utan ändringar, dock får ni gärna göra egna testprogram.) Till exempel: 9 5 4 3 1 9 tas bort, ersätts av 1. 1 byter plats med dess största barn, 5. 1 byter plats med dess största barn, 3. 1 har ej längre större barn, är på rätt plats. b) En annan tanke Anna har är att det vore trevligt om hon kunde använda sin prioritetskö till annat än bara Strings, som nu är fallet. Gör de ändringar som behövs för att göra Annas prioritetskö generisk, så att testprogrammet för del b fungerar. (1p) (Denna uppgift går att göra utan att del a har lösts.)