Tentamen Programmeringsteknik II 2016-01-11 Inledning I bilagan finns ett antal mer eller mindre ofullständiga klasser. Några ingår i en hierarki: List, SortedList, SplayList och ListSet enligt vidstående figur. Klassen List innehåller några grundläggande komponenter för att skapa och hantera enkellänkade listor av heltal. SortedList SplayList Klassen SortedList, som ärver från List, underhåller listor ListSet som är sorterade på datainnehållet. Klassen SplayList, som också ärver från List, ordnar om listan efter varje sökoperation så att det sökta värdet flyttas till början av listan. Tanken med detta är att ofta sökta värden samlas i början av listan och alltså hittas snabbt. Klassen ListSet som ärver från SortedList representerar en mängd dvs varje element förekommer högst en gång ( antingen är värdet med i mängden eller så är det inte med ). Vidare finns en klass BST som representerar binära sökträd med heltal som nycklar. Slutligen finns en Person-klass som representerar en person som håller reda på en sina föräldrar som också är Person-objekt. List
Del A (obligatorisk för alla) Svaren ska skrivas i rutorna och denna del av skrivningen ska lämnas in. A1. Metoden size i klassen List beräknar och returnerar listans längd (dvs antalet element). Skriv den eller de satser som saknas i rutan nedan public int size() { int result = 0; Node n = first; while (n!=null) { result++; n = n.next; A2. Klassen List ha en undantagsklass ListException som en inre klass. Skriv det som fattas i konstruktorn som gör att den lämpliga konstruktorn i basklassen anropas. public static class ListException extends RuntimeException { public ListException(String msg) { super(msg); A3. Metoden List copy() i klassen List returnerar ett nytt listobjekt som innehåller en kopia av noderna i den egna listan. Skriv den eller de satser (högst 2) som saknas i rutan nedan public List copy() { return new List(copy(first)); protected static Node copy(node n) { if (n==null) { return null; else { return new Node(n.data, copy(n.next));
A4. Metoden List above(int limit) returnerar ett nytt listobjekt som innehåller en kopia av de noder i den egna listan som är större än parametern limit. Skriv de satser som saknas i rutorna nedan public List above(int limit) { return new List(above(limit, first)); private static Node above(int limit, Node n) { if (n==null) { return null; else if (n.data > limit) { else { return new Node(n.data, above(limit, n.next)); return above(limit, n.next); A5. Metoden add(int data) i klassen SplayList ska lägga in ett nytt element först i listan (dvs före det tidigare första elementet). Skriv den sats som saknas i rutan nedan public void add(int data) { addfirst(data);
A6. Metoden contains(int data) i klassen SplayList ska, precis som samma metod i klassen List, returnera true om angivet värde finns i listan, annars false. Dessutom ska, om värdet hittas, detta värde flyttas fram och läggas först i listan. Se körexemplen! Skriv de satser (högst 4 stycken) som fattas i rutorna nedan. @Override public boolean contains(int data) { if (first==null) { return false; else if (first.data==data) { // No rearrangement needed return true; else { Node infrontof = first; // Find the node in front of the searched node while (infrontof.next!= null && infrontof.next.data!= data ) { infrontof = infrontof.next; if (infrontof.next == null) { return false; else { // Move to the front Node n = infrontof.next; infrontof.next = n.next; n.next = first; first = n; eller first = new Node(data, first); infrontof.next = infrontof.next.next; return true; A7. Rita det träd som genereras av main-metoden i klassen BST. Strukturen på trädet ska framgå liksom värdet på nycklarna (key).
A8. Metoden void insert(int key i klassen BST lägger in en ny nyckel i trädet med hjälp av metoden Node insert(int key, Node r). Skriv det som behövs för att inlägget ska fungera. public void insert(int key) { root = insert(key, root); A9. Givet att en metod för att multiplicera två 100 100-matriser tar 1 sekund. Hur lång tid kan förvänta sig att multiplikation av 1000 1000-matriser tar? Ledning: Att multiplicera två n n-matiser kräver att man beräknar n 2 element där varje element kräver cn operationer (c är en konstant). Svar: 1000 sekunder Motivering: (Du får skriva på baksidan av detta papper om du behöver mer utrymme.) Kort: T (n) = d n 3 ger att T (10n) = d (10n) 3 = 10 3 T (n) dvs 1000 gånger längre tid. Längre: Att multiplicera n n-matriser kräver Θ(n 3 ) operationer (n 2 element som vardera kräver c n operationer) dvs tiden T (n) d n 3. T (100) = 1 ger d = 10 6 och således T (10 3 ) = 10 6 (10 3 ) 3 = 10 3. Svaret är således 1000 sekunder. A10. Följande teknik kan användas för att rita rörliga figurer: while (...) { fig.draw() Thread.sleep(100); fig.move() // Rita figuren // Låt programmet sova en stund // Ändra figuren Denna teknik användes t ex i programmeringsteknik 1 för att flytta sköldpaddorna. Beskriv kortfattat (max 40 ord) den alternativa teknik som användes i denna kurs för den första obligatoriska uppgiften ( studsande bollar ) dvs en teknik inte använder Thread.sleep. Använd en Timer som genererar en händelse med jämna tidsintervall. I metoden som hanterar händelsen (en ActionListener) uppdateras figuren och ritas om.
Del B (för betyg 4 och 5) Svaren till dessa uppgifter skrivs på vanligt skrivningspapper. B1. Skriv metoden List reverse() i klassen List som returnerar ett nytt listobjekt med samma innehåll som den aktuella listan men med data i omvänd ordning. Se körexemplet! OBS: Metodens tidskomplexitet skall vara O(n)! public List reverse() { List result = new List(); for (Node n = first; n!=null; n = n.next) { result.addfirst(n.data); B2. Skriv klart iteratorn i klassen List dvs skriv den inre klassen Iterator samt metoden Iterator iterator() så att de fungerar enligt körexemplet i main-metoden. public class Iterator { Node current; public Iterator() { current = first; public boolean hasnext() { return current!=null; public int next() { int result = current.data; current = current.next; public Iterator iterator() { return new Iterator(); B3. Skriv klart klassen SortedList som subklass till klassen List som ser till att värdena lagras i stigande ordning. Metoden main med utskrifter visar vilka metoder som behövs och vad de ska göra. utskrifter public class SortedList extends List { /** * Adds a new data item keeping the list sorted. */ public void add(int data) { first = add(data, first); protected static Node add(int data, Node n) { if (n == null data<n.data) { return new Node(data, n); else { n.next = add(data, n.next); return n; @Override public void addfirst(int data) { throw new ListException("addFirst is illegal on sorted lists! ");
B4. Skriv klart klassen ListSet som en subklass till klassen SortedList. Ett objekt ur klassen ListSet skall representera en mängd av heltal dvs varje tal ska bara förekomma en gång. Se körexemplet! public class ListSet extends SortedList { public ListSet() { @Override public void add(int data) { first = add(data, first); protected static Node add(int data, Node n) { if (n==null data<n.data) { return new Node(data, n); else if (data==n.data) { return n; else { n.next = add(data, n.next); return n; B5. Skriv metoden List tolist() i klassen BST som returnerar ett List-objekt med noderna i storleksordning med minsta värdet först. OBS: Metoden skall ha tidskomplexiteten O(n)! public List tolist() { List result = new List(); tolist(root, result); private static void tolist(node r, List result) { if (r!=null) { tolist(r.right, result); // The trick is to do it from right to left result.addfirst(r.key); // A O(1)-operation tolist(r.left, result); B6. Givet att en (bra) implementation av mergesort tar 1 sekund för att sortera 10 4 objekt av något slag. Hur lång tid kan man förvänta sig att det tar att sortera 10 6 objekt? Motivera svaret! Mergesort är en Θ(n log n)-metod (oavsett hur indata är ordnat) dvs tiden T (n) växer som T (n) = c n log n. Eftersom T (10 4 ) enligt uppgiften är 1 sek kan en uppskattning av konstanten c beräknas ur T (10 4 ) = c 10 4 log(10 4 ) = 1 vilket ger c = 1 4 10 4 (Vi väljer naturligtvis att använda 10-logaritmen) Svaret är således 150 sekunder. T (10 6 ) = 1 4 10 4 10 6 log(10 6 ) = 6 4 102 = 150
B7. Klassen Person utgör noder i ett släktträd. Ett Person-objekt skall hålla reda på sina föräldrar (Person-objekt) som i sin tur håller reda på sina föräldrar etc. Den givna main-metoden bygger detta släktträd: Lisa Eva Anna Oskar Lasse Kalle Main och dess utskrifter visar vilka metoder klassen ska innehålla och vad de ska göra. Skriv klassen! public class Person { private String name; private Person mother; private Person father; public Person(String name) { this.name = name; public void addmother(person mother) { this.mother = mother; public void addfather(person father) { this.father = father; public String tostring() { return name; public ArrayList<Person>getGeneration(int generation) { ArrayList<Person> result = new ArrayList<Person>(); getgeneration(generation, this, result); private static void getgeneration(int generation, Person p, ArrayList<Person> result) { if (p!=null) { if (generation==0) { result.add(p); else { getgeneration(generation-1, p.mother, result); getgeneration(generation-1, p.father, result);