INDA Fikitv tenta Föreläsning 02 feb 19, tisdag v8 READ THESE INSTRUCTIONS VERY CAREFULLY. YOUR SUCCESS ON THIS EXAM MIGHT DE- PEND ON IT. IF YOU DO NOT FOLLOW THESE INSTRUCTIONS, WE WILL BE COMPLETELY MER- CILESS. There are three parts to this exam. The point values of the first, second, and third parts are 26, 26, and 48 points respectively. You may use your points for Quiz1 (kontrollskrivning 1) instead of taking the first part of the exam. Likewise and independently, you may use your points from Quiz2 (kontrollskrivning 2) instead of taking the second part of the exam. As for the third part of the exam, you start with the points you have earned from your A-homeworkassignments and B-homework-assignments You need 50 points to pass this exam. The number of points required for a 4 on the exam is 74 and for 5 89 points and for a 6 100 points. The grade of the exam and the grade for the laborations gives the grade of the course. So you do not need to take the exam provided you are satisfied the grade of the examination part corresponing to the points you already have. NOTE: You must decide whether to use any of your quiz points before you turn in your papers. You must put a note on the cover page (i.e., the blue page where your name and ID number is written) clearly telling us what you want us to do. If you tell us that you want, for example, to use your points from Quiz1, then we will not even look at anything you might have written for the first part of the exam. WARNING!!!!!!!!! (1) If you do not tell us what to do with your quiz points for either quiz, then we will BY DEFAULT use your quiz points - even if you have solved the problems on the tenta and even if you got ZERO points on the quiz. (2) Your instructions must be clearly written on your blue cover sheet, otherwise they will be ignored. Inga hjälpmedel tillåtna. Lycka till! Del I 1. Fibonacci talföljd fib(i), i >= 0, definieras som fib(0) = 0, fib(1) = 0 fib(n) = fib(n-1) + fib(n-2) Skriv i Java två klassmetoder, en rekursiv och en iterativ, som beräknar fib(i).
2. Vad skrivs ut om detta program körs (OBS ibland twice, iblad twiced)? 8p) public class RefMM { public static void main(string [] argv ) { int i = 3; int j = 4; System.out.println("i = " + i + " j = " + j); j = twiced(i); System.out.println("i = " + i + " j = " + j); i = 3; j = 4; System.out.println("i = " + i + " twice(i); System.out.println("i = " + i + " j = " + j); j = " + j); int [] a = new int [2]; a[0] = 1; a[1] = 2; int [] b = new int [2]; b[0] = 5; b[1] = 7; System.out.print( "a ={" + a[0] + "," + a[1] + ""); System.out.println(" b ={" + b[0] + "," + b[1] + ""); b = twicedarr(a); System.out.print( "a ={" + a[0] + "," + a[1] + ""); System.out.println(" b ={" + b[0] + "," + b[1] + ""); a[0] = 1; a[1] = 2; b[0] = 5; b[1] = 7; System.out.print( "a ={" + a[0] + "," + a[1] + ""); System.out.println(" b ={" + b[0] + "," + b[1] + ""); twicearr(a); System.out.print( "a ={" + a[0] + "," + a[1] + ""); System.out.println(" b ={" + b[0] + "," + b[1] + ""); private static int twiced(int ii) { return ii *ii; private static void twice(int ii) { ii = ii *ii; private static int [] twicedarr(int [] ia) { int [] result = new int [ia.length]; for (int k = 0; k < ia.length; k = k+1) { result[k] = ia[k]*ia[k]; return result; private static void twicearr(int [] ia) { for (int k = 0; k < ia.length; k = k+1) { ia[k] = ia[k]*ia[k];
Här kommer det på den riktiga tentan flervalsfågor 3 <= fråga <= 6 som liknar kontrollskrivning 1 Flervalsfrågorna för del I och del II på särskilt blad som lämnas in. Del II Här kommer det på den riktiga tentan flervalsfågor 7 <= fråga <= 10 som liknar kontrollskrivning 2 11 Städer har alltid ett namn och ett visst antal innevånare. Vissa städer (t ex Umeå och Nyköping) är residensstäder och har då en landshövding, andra städer (t ex Strängnäs, Lund och Skara) är stiftsstäder och har en biskop. a) Antag tills vidare (uppgift 1 a) till 1 f)) att inga städer kan vara kombinerade stifts- och residensstäder. Modellera i Java med tre klasser denna situation, som den dessutom beskrivs med nedanstående UML-liknade klassdiagram. De tre klasserna som skall skrivas skall dessutom ha lämpliga konstruerare som initierar attributen(instansvariablerna). Stad int inv String namn String vilketnamn() int antalinnevånare() Residensstad String landshövding String vemärlandshövding() Stiftsstad String biskop String vemärbiskop() b) Klassen Stad är inte abstrakt. Varför? c) Antag att vi i en Java-klass C har en deklaration Stad [] stad; och att stad refererar till ett arrayobjekt som innehåller uppgifter om städer av olika slag. Hur skriver man i klassen C en metod som skriver ut (på System.out) uppgifterna om städerna? För alla städer skall namn och innevånarantal anges, i förkommande fall även namn på landshövding och biskop. Uppgiften skall lösas enbart med de metoder som finns i klassdiagrammet. (Jämför även uppgift1 c) och 1d)) d) I uppgift c) tvingades vi kontrollera vilken sorts stad som vi skulle skriva ut information om. Detta anses inte som bra OO-programmering. Varför?
e) En bättre lösning är att alla de tre klasserna i klassdiagrammet förses med en metod String info() som retunerar lämplig information för de olika städerna. Skriv metoden för de tre klasserna. Skriv också en ny lösning på uppgiften i c), som nu kan lösas på "OO-sätt". f) Fyll arrayen stad i uppgift 1c med en vanlig stad, en stiftsstad och en residensstad. (t ex Örnsköldsvik med 56658 innevånare, Lund med 97975 innevånare och biskopen Cristina Odelberg, Umeå med 103517 innevånare och landshövdingen Georg Andersson) g) "Metropoler" (som t. ex Stockholm och Luleå) är både stifts- och residensstäder. I många OO-språk kan detta modelleras med en ny fjärde klass StiftsOchResidensstad som ärver både Stiftsstad och Residensstad. Detta kan man inte göra i Java. Hur kan man göra istället? För full poäng skall det finnas ett begrepp som kan användas som typnamn för residensstäder, vare sig de är enbart residensstäder eller "metropoler", och ett begrepp som kan användas som typnamn för stiftsstäder, vare sig de är enbart stiftsstäder eller "metropoler". Del III 8. 12. Implementera en "double-ended queue" som implementerar ADT Deque definerat med nedanstående gränssnitt: public interface Deque { public int size() ; // Antalet objekt i kön public boolean isempty(); // Är kön tom? public Object first() throws QueueEmptyException ; // Objekt som är först public Object last() throws QueueEmptyException; // Objekt som är sist public void insertfirst(object e); // nytt objekt sist public void insertlast(object e); // nytt objekt först public void removefirst() throws QueueEmptyException ;// Avlägsna första objektet public void removelast() throws QueueEmptyException ; // Avlägsna det sista objektet Tips. Rita gärna en bild över din lösning. 13. Visa bokens sats 10.1: Höjden på trädet som illustrerar körningen av merge-sort på en följd med storlek n har höjden [log2 n] (taket) 14. Visa hur man med "in-place heap-sort" gör en lexiografisk sortering av strängar. Svara med sucessiva bilder på vektorn och motsvarande heap hur dessa strängar sorteras: zb pe mm fg ae ma vm. Vilken komplexitet har heapsorteringen-sorteringen?
Förslag till svar tenatamen i Inroduktion till datalogi 2002 mars 09. 1. public class TestFib { public static void main(string argv[]) { System.out.println(fibIter(10)); System.out.println(fibRek(10)); ; public static int fibrek(int i) { if (i < 0 ) { throw new RuntimeException("Felaktigt argument till fibrek()"); switch ( i ){ case 0 : return 0; case 1 : return 1; default : return fibrek(i-1) +fibrek(i-2); public static int fibiter(int i) { int old; int vold; int ny = 1; int j; if (i < 0 ) { throw new RuntimeException("Felaktigt argument till fibiter()"); switch ( i ){ case 0 : return 0; case 1 : return 1; default : vold = 0; old = 1; j = 1; while (j < i) { ny = vold + old; j = j+1; vold = old; old = ny; return ny; 2 i = 3 j = 4 i = 3 j = 9 i = 3 j = 4 i = 3 j = 4 a ={1,2 b ={5,7 a ={1,2 b ={1,4 a ={1,2 b ={5,7 a ={1,4 b ={5,7
11. public class Stad { //a int inv; String name; public Stad(int iinv, String iname) { inv = iinv; name = iname; public String vilketnamn() { return name; public int antalinnevånare() { return inv; public String info() { return (name + " " + inv); //Tillägg e ipublic class Stiftsstad extends Stad { String biskop; public Stiftsstad(int iinv, String iname, String ibiskop) { super(iinv, iname); biskop = ibiskop; public String vemärbiskop() { return biskop; public String info() {return super.info() + " biskop : " + biskop; //Tillägg e public class Residensstad extends Stad { String landsh; public Residensstad(int iinv, String iname, String ilandshövding){ super(iinv, iname); landsh = ilandshövding; public String vemärlandshövding() { return landsh; public String info() {return super.info()+" landshövding : "+landsh; //Tillägg e //b Det finns städer som "bara" är städer och måste kunna instansieras. Abstrakta klasser kan inte instansieras. public void skriv() { // c for (int i = 0; i < stad.length; i = i+1) { System.out.print(stad[i].vilketNamn() + " " + stad[i].antalinnevånare() + " "); if (stad[i] instanceof Residensstad) { System.out.println("lh : " + ((Residensstad) stad[i]).vemärlandshövding()); else if (stad[i] instanceof Stiftsstad) { System.out.println("biskp: "+ ((Stiftsstad) stad[i]).vemärbiskop()); else { System.out.println();
Vi tvingas ofta att skriva tillägg i användande klasser när ny subklasser av t ex stad införes, t ex i skriv()-metoden // d i 1 b)ovan. Svårt komplettera program. public void skrivoo() { // e for (int i = 0; i < stad.length; i = i+1) { System.out.println(stad[i].info()); //Även tillägg i de tre stadsklaserrna, se under 1 a. Stad [] stad = // f { new Stad(56658, "Örnsköldsvik"), new Residensstad(103517, "Umeå", "Georg Andersson"), new Stiftsstad(97975, "Lund", "Cristina Odelberg"); Man får nöja sig med att ärva enkelt och ersätta det andra arvet med att implementera ett gränssnitt. //g Även klassen Stiftsstad låter man implementera gränssnittet. (Bättre språkligt låta SitftsstadIF heta Stiftsstad och döpa om Stiftsstad till RenStiftstad eller dylikt, men orkar inte göra detta.) public interface StiftsstadIF { public String vemärbiskop() ; public class StiftsOchResidensstad extends Residensstad implements StiftsstadIF{ String biskop; public StiftsOchResidensstad(int iinv, String iname, String ibiskop, String ilandshövding) { super(iinv, iname, ilandshövding); biskop = ibiskop; public String vemärbiskop() { return biskop; public String info() { return super.info() + " biskop : " + biskop; 12. public class DLDeque implements Deque { private int size = 0; private DLNode sentinel; public DLDeque() { sentinel = new DLNode(null,null, null); sentinel.setleft(sentinel); sentinel.setright(sentinel); public int size() { return size;
public boolean isempty() { return size == 0; public Object first() throws QueueEmptyException { if (isempty()) { throw new QueueEmptyException("Empty Queue"); else { return (sentinel.right()).element(); public Object last() throws QueueEmptyException { if (isempty()) { throw new QueueEmptyException("Empty Queue"); else { return (sentinel.left()).element(); public void insertfirst(object e) { DLNode ny = new DLNode(e, sentinel, sentinel.right()); (sentinel.right()).setleft(ny); sentinel.setright(ny); size = size + 1; public void insertlast(object e) { DLNode ny = new DLNode(e, sentinel.left(), sentinel); (sentinel.left()).setright(ny); sentinel.setleft(ny); size = size + 1; public void removefirst() throws QueueEmptyException { if (isempty()) { throw new QueueEmptyException("Empty priority queue!"); else { sentinel.setright( (sentinel.right()).right()); (sentinel.right()).setleft(sentinel); size = size -1; public void removelast() throws QueueEmptyException { if (isempty()) { throw new QueueEmptyException("Empty priority queue!"); else {
sentinel.setleft( (sentinel.left()).left()); (sentinel.left()).setright(sentinel); size = size -1; public class DLNode { private Object element; private DLNode left; private DLNode right; /** constructor with parameters */ public DLNode(Object e) { this(e, null, null); /** constructor with parameters */ public DLNode(Object e, DLNode ileft, DLNode iright ) { setelement(e); left = ileft; right = iright; public Object element() { return element; public void setelement(object o) { element=o; public DLNode left() {return left; public void setleft(dlnode ileft) {left = ileft; public DLNode right() {return right; public void setright(dlnode iright) {right = iright; 3 0 tom deque deque med 3 element vaktpost, sentinel vaktpost, sentinel david adam bertil
13. Mergesort delar rekursivt de distinkta elementen som skall sorteras i två delar: Den rekursiva arbetet kan illustreras med ett "mergesort-träd" med noder som innehåller de element som skall sortras i ett viss anrop. Djupet på en nod i trädet är antalet rekursiva anrop man gjort för att komma till anropet av sorteringen av elmenten i noden: 85 24 63 45 17 31 96 50 85 24 63 45 17 85 24 63 45 17 31 96 50 85 24 63 45 17 85 24 63 45 17 31 96 50 85 24 63 45 17 85 24 63 45 17 31 96 50 85 24 Antalet element som skall sorteras är n. Trädet ovan till vänster med n = 8 har höjden 3. Maximalt antal element för givit djup d är uppenbarligen när hela nedersta nivån i trädet är fullt, vilket inträffar för n = 2d. Följaktligen gäller n <= 2d. (1) Värsta fallet inträffar nedersta nivån i träet bara innehåller ett två element, t ex fallet ovan till höger. Då gäller föjande hjälpsats:: Påstående: 2d-1 + 1 = n, där n är antalet noder i mergesort-trädet med höjden d. Bevis. I. basfall. Påstående gäller d = 1 (och man kan på samma sätt visa att det är sant för d= 0, 2, 3 t ex) 85 24 63.... 85 24 85 24 63 85 24 85 24 63 85 24 Sträckat utökning av ojämt träd med höjd d till ett maximalt ojämt träd med höjd d+1 genom tillägg av jämt träd V. L. = 2 1-1 + 1= 2 0 + 1 = 1 + 1 = 2 H.L. = 2 V.L. =H.L Bevis. II. Induktivt fall. Förutsättning : 2d-1 +1 = n för fixt d, n antalet noder i sämsta mergesort-trädet med djupet d Påstående : 2d+1-1 +1 = n, n antalet noder i sämsta mergesort-trädet med djupet d+1 Bevis: V.L. = 2d +1 H.L = "gamla trädet med 2 d-1 + 1 " + "jämt ytterligare träd med 2 d-1 ", se ill ovan = = 2 d-1 + 1 + 2 d-1 = 2* 2 d-1 + 1 = 2 d + 1 V.L. = H.L. Eftersom2d-1 + 1 = n så följer att 2d-1 < n. (2) (1) och (2) ger 2d-1 < n <= 2d varav d-1 < log 2 n <= d vilket kan skrivas som [log 2 n]. V. S.V
14. Vektorn zb pe mm fg ae ma vm heap osorterat Motsvarande heap zb pe mm fg ae ma vm zb ingen bubbling heap osorterat pe zb pe mm fg ae ma vm zb ingen bubbling heap osorterat pe mm zb pe mm fg ae ma vm zb ingen bubbling heap osorterat pe mm fg zb pe mm fg ae ma vm zb ingen bubbling heap osorterat pe mm fg ae zb pe mm fg ae ma vm zb ingen bubbling heap osorterat pe mm fg ae ma zb pe mm fg ae ma vm zb zb heap osorterat pe mm pe vm fg ae ma vm fg ae ma mm Up-Bubbling! zb pe vm fg ae ma mm heap mm pe vm fg ae ma zb mm vm heap sorterat pe vm pe mm fg ae ma fg ae ma Ner-Bubbling! vm pe mm fg ae ma zb heap sorterat ma pe mm fg ae vm zb ma pe heap sorterat pe mm ma mm fg ae fg ae Ner-Bubbling!
pe ma mm fg ae vm zb heap sorterat ae ma mm fg pe vm zb ae mm heap sorterat ma mm ma ae fg fg Ner-Bubbling! mm ma ae fg pe vm zb heap sorterat fg ma ae mm pe vm zb fg ma heap sorterat ma ae fg ae Ner-Bubbling! ma fg ae mm pe vm zb heap sorterat ae fg ma mm pe vm zb ae fg heap sorterat fg ae Ner-Bubbling! fg ae ma mm pe vm zb heap sorterat ae fg ma mm pe vm zb ae heap sorterat ae fg ma mm pe vm zb sorterat Puh!