1(5) Institutionen för datavetenskap LUNDS TEKNISKA HÖGSKOLA Tentamen, EDAA01 Programmeringsteknik – fördjupningskurs 2015–03–17, 14.00–19.00 Anvisningar: Denna tentamen består av 4 uppgifter. Preliminärt ger uppgifterna 1. 2. 3. 4. 2+1+1+2+2=8 5 + 4 + 1 = 10 p 2+2+5=9p 1+1+1+6=9p Tillåtet hjälpmedel: Java snabbreferens. För full poäng ska dina lösningar inte vara onödigt ineffektiva. I slutet av tentamen finns dokumentation av någon/några klasser och interface i Java Collections Framework. När rättningen är klar meddelas detta på kursens hemsida (cs.lth.se/edaa01). 1. a) Beskriv likheter och skillnader mellan ett interface och en abstract klass. b) Ett binärt träd (ej sökträd) innehåller sju noder med heltalen 1-7. De tre olika rekursiva sätten att traversera trädet ger resultatet nedan. Rita trädet! Preorder: 1 2 4 3 5 7 6 Inorder: 2 4 1 5 7 3 6 Postorder: 4 2 7 5 6 3 1 c) Förklara vad som menas med en kollision i en hashtabell. d) Antag att vi har har deklarerat och skapat följande map: Map<Player, Integer> map = new HashMap<Player, Integer>(); Vad ställer det för speciella krav på klassen Player? Motivera ditt svar. e) Antag att en vektor innehåller ett antal sorterade tal. Lägg till några få osorterade tal efter de redan sorterade talen. Sortera sedan hela vektorn på nytt. Vad får denna sortering för tidskomplexitet om man använder insättningssortering respektive mergeSort. Motivera ditt svar. 2(5) 2. a) Antag att vi har specificerat den abstrakta datatypen Stack i följande interface: public interface Stack<E> { /** * Pushes an element onto this stack. * @param e the element to push */ void push(E e); /** * Removes and returns the element on the top of this stack. * @return the element at the top of this stack or null if this stack is empty */ E pop(); /** * Retrieves, but does not remove, the element on the top of this stack. * @return the element at the top of this stack or null if this stack is empty */ E peek(); /** * Returns true if this stack contains no elements. * @return true if this stack contains no elements */ boolean isEmpty(); } Skriv en klass som implementerar interfacet Stack. Elementen i stacken ska lagras i en enkellänkad lista. Noderna i denna lista ska representeras av följande nästlade klass. /* Nested class. Represents a node which contains an element of type E. */ static class ListNode<E> { private E element; private ListNode<E> next; /* Creates a listnode which contains e. */ private ListNode(E e) { element = e; next = null; } } För full poäng får ingen av metoderna ha högre tidskomplexitet än O(1). b) Skriv en subklass till den stackklass du skrev i deluppgift a. Klassen ska innehålla en metod som tar bort de n översta värdena på stacken och returnerar dem i en lista. Metodens returtyp ska vara List<E>. (List är interfacet java.util.List). Om antal element i stacken är mindre än n ska alla element tas bort. Om n är mindre än ett ska IllegalArgumentException genereras. c) Ange någon annan datastruktur som kan användas för att effektivt implementera en stack. Beskriv hur datastrukturen ska användas så att alla metoder får tidskomplexitet O(1). 3(5) 3. a) För att representera ett binärt sökträd (ej balanserat) kan följande klasser användas: public class BinarySearchTree<E extends Comparable<E>> { private Node<E> root; /** Skapar ett tomt binärt träd. */ public BinarySearchTree() { root = null; } ... metoder ... private static class Node<E> { private E element; private Node<E> left; private Node<E> right; private Node(E element) { this.element = element; left = null; right = null; } } } Antag att följande metoder lagts till i klassen BinarySearchTree<E>. Programkoden innehåller en felaktighet eller olämplighet. Förklara vad som är fel/olämpligt. Rätta också till programkoden. /** Beräknar trädets höjd. */ public int height() { return height(root); } private int height(Node<E> n) { if (n == null) { return 0; } else if (height(n.left) > height(n.right)) { return 1 + height(n.left); } else { return 1 + height(n.right); } } b) Antag att följande metoder lagts till i klassen BinarySearchTree<E>. Programkoden innehåller en felaktighet eller olämplighet. Förklara vad som är fel/olämpligt. Rätta också till programkoden. /** Lägger till x längst ned till vänster i trädet. */ public void addLeft(E x) { addLeft(root, x); } private void addLeft(Node<E> n, E x) { if (n == null) { n = new Node<E>(x); } else { addLeft(n.left, x); } } 4(5) c) Vi fortsätter med rekursion men nu handlar det om binära tal. Ett decimalt heltal n i (tal i basen 10) kan omvandlas till binär representation (samma tal i talbasen 2) med hjälp av följande observationer: • Den binära representationen av det decimala talet 0 är 0. • När n är större än 0 består dess binära representation av den binära representationen för n/2 följt av siffran n%2 d.v.s. resten vid heltalsdivision med 2. Exempel: Talet 9 har den binära representationen 1001, vilket består av 100 som är den binära representationen av 4 (9/2) följt av siffran 1 (9%2). Implementera med hjälp av detta en rekursiv metod public static String binary(int n); som returnerar en sträng innehållande den binära representationen av ett positivt decimalt heltal. Ledningar och anvisningar: • Strängen får inte innehålla onödiga tecken. Speciellt får det inte finnas någon inledande nolla när metoden anropas för n > 0. • Det är (naturligtvis) tillåtet att lägga till en privat hjälpmetod. • Låt metoden generera IllegalArgumentException om parametern är ett negativt tal. 4. När man ska samsortera k sorterade vektorer kan man använda en generalisering av merge-steget i Mergesort. Man sätter in det första elementet från var och en av vektorerna i någon datastruktur. I varje steg tar man sedan ut det minsta elementet ur denna struktur, lägger detta i resultatvektorn och sätter i datastrukturen i stället in nästa element ur den vektor varifrån det minsta elementet kom. En heap är då ett lämpligt val av datastruktur för att hålla reda på de k element från vilka minimum skall utväljas. Antag att man har 6 vektorer v1,...,v6 innehållande heltal enligt följande: v1 v2 v3 v4 v5 v6 = = = = = = {4, {1, {5, {7, {2, {3, 6, 2, 7, 9, 3, 4, ...} ...} ...} ...} ...} ...} a) Visa hur heapen ser ut när man satt in det första elementet från var och en av de sex vektorerna. Utgå ifrån att man sätter in dem i den ordning som vektorerna är uppräknade ovan. Visa steg för steg hur heapen ser ut efter insättning av vart och ett av elementen. b) Visa hur heapen ser ut när man plockat bort det minsta elementet ur den heap som byggts i a samt satt in det andra elementet från den vektor från vilken det minsta elementet kom. Visa detta i två steg, d.v.s. först heapens utseende efter borttagningen och därefter efter insättningen. c) Man brukar implementera en heap med hjälp av en vektor. Förklara varför. Visa också hur en vektor motsvarande heapen efter sista steget i b ser ut. d) I den här uppgiften ska du implementera en metod som samsorterar ett antal vektorer med den metod som beskrivs ovan. Metoden ska ha följande rubrik: public static <T extends Comparable<T>> void mergeArrays(List<T[]> arrays) Ledningar och anvisningar: • Listan arrays innehåller vektorerna som ska samsorteras. Metoden mergeArrays ska skriva ut det samsorterade resultatet på System.out med ett element per rad. • Klassen PriorityQueue<E> är implementerad med hjälp av en heap och ska användas för att lösa uppgiften. 5(5) • När man hämtat det minsta elementet från heapen ska man hämta nästa vektorelement från den vektor detta element kom ifrån. Det räcker alltså inte med att lagra elementen av typen T i heapen. Man måste också hålla reda på elementets ursprungsvektor. Därför behövs en klass ArrayContainer<T> som håller reda på en vektor samt aktuell position i vektorn. Klassen ArrayContainer<T> ser ut så här: public class ArrayContainer<T extends Comparable<T>> implements Comparable<ArrayContainer<T>> { private T[] a; private int index; /** Skapar ett objekt som håller reda på en vektor samt aktuell position i vektorn (0 från början). */ public ArrayContainer(T[] a) { this.a = a; index = 0; } /** Returnerar true om det finns fler element att hämta från vektorn. */ public boolean moreElements() { return index < a.length; } /** Returnerar aktuellt element i vektorn och flyttar fram aktuell position ett steg. */ public T getNextElement() { return a[index++]; } /** Jämför aktuellt element i denna vektor med aktuellt element i other. */ public int compareTo(ArrayContainer<T> other) { return a[index].compareTo(other.a[other.index]); } } java.lang Interface Iterable<T> Type Parameters: T - the type of elements returned by the iterator Modifier and Type Method and Description Iterator<T> iterator() Returns an iterator over a set of elements of type T. java.util Interface Iterator<E> Type Parameters: E - the type of elements returned by this iterator • Methods Modifier and Type boolean E void Method and Description hasNext() Returns true if the iteration has more elements. next() Returns the next element in the iteration. remove() Removes from the underlying collection the last element returned by this iterator (optional operation). java.lang Interface Comparable<T> Type Parameters: T - the type of objects that this object may be compared to Modifier and Type Method and Description int compareTo(T o) Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object. java.lang Interface Comparator<T> Type Parameters: T - the type of objects that may be compared by this comparator Modifier and Type int Method and Description compare(T o1, T o2) Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second. java.util Class PriorityQueue<E> Type Parameters: E - the type of elements held in this collection Constructor Summary PriorityQueue() Creates a PriorityQueue with the default initial capacity (11) that orders its elements according to their natural ordering. PriorityQueue(Collection<? extends E> c) Creates a PriorityQueue containing the elements in the specified collection. PriorityQueue(int initialCapacity) Creates a PriorityQueue with the specified initial capacity that orders its elements according to their natural ordering. PriorityQueue(int initialCapacity, Comparator<? super E> comparator) Creates a PriorityQueue with the specified initial capacity that orders its elements according to the specified comparator. Method Summary boolean add(E e) Inserts the specified element into this priority queue. void clear() Removes all of the elements from this priority queue. Comparator<? super E> boolean comparator() Returns the comparator used to order the elements in this queue, or null if this queue is sorted according to the natural ordering of its elements. contains(Object o) Returns true if this queue contains the specified element. More formally, returns true if and only if this queue contains at least one element e such that Iterator<E> o.equals(e). iterator() boolean offer(E e) Returns an iterator over the elements in this queue. Inserts the specified element into this priority queue. E peek() Retrieves, but does not remove, the head of this queue, or returns null if this queue is empty. E poll() Retrieves and removes the head of this queue, or returns null if this queue is empty. boolean remove(Object o) Removes a single instance of the specified element from this queue, if it is present. More formally, removes an element e such that o.equals(e), if this queue contains one or more such elements. Returns true if and only if this queue contained the specified element (or equivalently, if this queue changed as a result of the call). int size() Returns the number of elements in this collection. boolean isEmpty() Object[] toArray() Returns true if this collection contains no elements. Returns an array containing all of the elements in this queue. <T> T[] toArray(T[] a) Returns an array containing all of the elements in this queue; the runtime type of the returned array is that of the specified array.
© Copyright 2024