Tentamen Programmeringsteknik II Skrivtid: Hjälpmedel: Java-bok (vilken som helst) Skriv läsligt! Använd inte rödpenna!

Relevanta dokument
Tentamen Programmeringsteknik II Skrivtid: Hjälpmedel: Java-bok (vilken som helst) Skriv läsligt! Använd inte rödpenna!

Det är principer och idéer som är viktiga. Skriv så att du övertygar rättaren att du har förstått dessa även om detaljer kan vara felaktiga.

Det är principer och idéer som är viktiga. Skriv så att du övertygar rättaren om att du har förstått dessa även om detaljer kan vara felaktiga.

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

Det är principer och idéer som är viktiga. Skriv så att du övertygar rättaren om att du har förstått dessa även om detaljer kan vara felaktiga.

Observera. Tentamen Programmeringsteknik II Skrivtid:

Lägg uppgifterna i ordning. Skriv uppgiftsnummer och din kod överst i högra hörnet på alla papper.

Tentamen Programmeringsteknik 2 och MN Skrivtid: Inga hjälpmedel.

Lägg uppgifterna i ordning. Skriv uppgiftsnummer och din kod överst i högra hörnet på alla papper.

Lägg uppgifterna i ordning. Skriv uppgiftsnummer och din kod överst i högra hörnet på alla papper.

Det finns en referensbok (Java) hos vakten som du får gå fram och läsa men inte ta tillbaka till bänken.

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

public boolean containskey(string key) { return search(key, head)!= null; }

Klassen BST som definierar binära sökträd med tal som nycklar och enda data. Varje nyckel är unik dvs förekommer endast en

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

Tentamen Programmeringsteknik II för STS Skrivtid: Inga hjälpmedel.

Det finns en referensbok (Java) hos tentavakten som du får gå fram och läsa men inte ta tillbaka till bänken.

Obligatorisk uppgift 5

Tentamen Programmeringsteknik II Inledning. Anmälningskod:

Lägg uppgifterna i ordning. Skriv uppgiftsnummer och din kod överst i högra hörnet på alla papper.

Det finns en referensbok (Java) hos vakten som du får gå fram och läsa men inte ta tillbaka till bänken.

Det finns en referensbok (Java) hos tentavakten som du får gå fram och läsa men inte ta tillbaka till bänken.

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

if (n==null) { return null; } else { return new Node(n.data, copy(n.next));

Det finns en referensbok (Java) hos tentavakten som du får gå fram och läsa men inte ta tillbaka till bänken.

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

Det är principer och idéer som är viktiga. Skriv så att du övertygar examinatorn om att du har förstått dessa även om detaljer kan vara felaktiga.

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

Det finns en referensbok (Java) hos vakten som du får gå fram och läsa men inte ta tillbaka till bänken.

Tentamen Programmeringsteknik II och NV2 (alla varianter) Skriv bara på framsidan av varje papper.

Det finns en referensbok (Java) hos tentavakten som du får gå fram och läsa men inte ta tillbaka till bänken.

Tentamen, Algoritmer och datastrukturer

Det finns en referensbok (Java) hos tentavakten som du får gå fram och läsa men inte ta tillbaka till bänken.

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

Det finns en referensbok (Java) hos vakten som du får gå fram och läsa men inte ta tillbaka till bänken.

Tentamen i Programmeringsteknik I

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

Tentamen i Programmeringsteknik I

Grafik, grafiska användargränssnitt och rörliga bilder

Tänk på följande: Det finns en referensbok (Java) hos tentavakten som du får gå fram och läsa men inte ta tillbaka till bänken.

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

Det finns en referensbok (Java) hos tentavakten som du får gå fram och läsa men inte ta tillbaka till bänken.

Del A (obligatorisk för alla)

Lösningsförslag till exempeltenta 1

Lägg uppgifterna i ordning. Skriv uppgiftsnummer och din anmälningskod överst i högra hörnet på alla papper.

TENTAMEN: Algoritmer och datastrukturer. Läs detta! Uppgifterna är inte avsiktligt ordnade efter svårighetsgrad.

Lägg uppgifterna i ordning. Skriv uppgiftsnummer och din anmälningskod överst i högra hörnet på alla papper.

F5: Debriefing OU2, repetition av listor, träd och hashtabeller. Carl Nettelblad

List.java. List.java. Printed by Tom Smedsaas

Variabler som hör till enskilda objekt. Deklareras på översta nivån i klassen och i regel som private.

Sammanfattning och repetition utgående från typiska tentamensuppgifter

Obligatorisk uppgift 5: Symbolisk kalkylator

1 Uppgift 1. a) Skapar ett Company-objekt med hjälp av den överlagrade konstruktorn. Du kan själv välja värden på instansvariablerna.

Föreläsning 9 Innehåll

Föreläsning 9 Innehåll

Tentamen i Algoritmer & Datastrukturer i Java

TENTAMEN OOP

Konstruktion av klasser med klasser

Tentamen i Programmeringsteknik I

Föreläsning 7. Träd och binära sökträd

BST implementering, huvudstruktur

Interface. Interface. Tobias Wrigstad (baserat på bilder från Tom Smedsaas) 3 december 2010

Tentamen Datastrukturer (DAT036)

Dugga Datastrukturer (DAT036)

Datastrukturer i kursen. Föreläsning 8 Innehåll. Träd rekursiv definition. Träd

TENTAMEN: Algoritmer och datastrukturer. Läs detta!

TENTAMEN PROGRAMMERINGSMETODIK MOMENT 2 - JAVA, 4P

Tentamen, EDA501/EDAA20 Programmering M MD W BK L

Obligatorisk uppgift: Symbolisk kalkylator

Tentamen Datastrukturer, DAT037 (DAT036)

DAT043 Objektorienterad Programmering

Klasshierarkier. Klasser kan byggas på redan definierade klasser

Inlämningsuppgiften. Föreläsning 9 Innehåll. Träd. Datastrukturer i kursen

public och private Obs: private inte skyddar mot access från andra objekt i samma klass.

LÖSNINGSFÖRSLAG Programmeringsteknik För Ing. - Java, 5p

Omtentamen för TDA540 Objektorienterad Programmering. Institutionen för Datavetenskap CTH HT-16, TDA540. Dag: , Tid:

Föreläsning 5-6 Innehåll. Exempel på program med objekt. Exempel: kvadratobjekt. Objekt. Skapa och använda objekt Skriva egna klasser

TENTAMEN OOP

Omtentamen för TDA540 Objektorienterad Programmering. Institutionen för Datavetenskap CTH HT-16, TDA540. Dag: , Tid:

Föreläsning 3: Abstrakta datastrukturer, kö, stack, lista

Exempel på listor (klassen ArrayList). Ett exempel med fält. Avbildning är en speciell typ av lista HashMap.

TENTAMEN OOP

Lösningar till Tentamen i Programmeringsteknik II och MN

Föreläsning 5-6 Innehåll

Tentamen. Lösningsförslag

Tentamen Datastrukturer (DAT036)

2D1311 Programmeringsteknik för Bio1 och Bio2, vt 2003 Fiktivt prov På flervalsfrågorna är endast ett svar rätt om inget annat anges i frågan! Det rik

Idag. Javas datatyper, arrayer, referenssemantik. Arv, polymorfi, typregler, typkonvertering. Tänker inte säga nåt om det som är likadant som i C.

Dagens föreläsning. Arrayer och klasser. Medan ni väntar: Gå till m.voto.se/prog11 och svara på några gamla tentamensfrågor! (26 januari 2018 F3 1 )

F4: Mer om OU1, OU2, listor och träd. Carl Nettelblad

Tentamen i Algoritmer & Datastrukturer i Java

Sammanfattning och repetition utgående från typiska tentamensuppgifter

Del A (obligatorisk för alla)

Inom datalogin brukar man använda träd för att beskriva vissa typer av problem. Om man begränsar sig till träd där varje nod förgrenar sig högst två

Tentamen i Algoritmer & Datastrukturer i Java

Programmering för språkteknologer II, HT2014. Rum

Dagens program. Programmeringsteknik och Matlab. Objektorienterad programmering. Vad är vitsen med att ha både metoder och data i objekten?

/* * * Lösningsförslag tentamen DIT950 * Datum * */ /* * -1 - */ För samtliga gäller,se föreläsningsanteckningar.

Transkript:

Tentamen Programmeringsteknik II 2013-10-22 Skrivtid: 0800-1300 Hjälpmedel: Java-bok (vilken som helst) Tänk på följande Skriv läsligt! Använd inte rödpenna! Skriv bara på framsidan av varje papper. Börja alltid ny uppgift på nytt papper. Lägg uppgifterna i ordning. Skriv uppgiftsnummer och din kod på alla papper. Skriv inte längst upp i vänstra hörnet - det går inte att läsa där efter sammanhäftning. Fyll i försättssidan fullständigt. Det är principer och idéer som är viktiga. Skriv så att du övertygar rättaren att du har förstått dessa även om detaljer kan vara felaktiga. Programkod skall vara läslig dvs den skall vara vettigt strukturerad och indenterad. Namn på variabler, metoder, funktioner, klasser etc skall vara beskrivande men kan ändå hållas ganska korta. Såvida inget annat anges så får man bygga på lösningar till föregående uppgifter även om dessa inte har lösts. Det är 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. Uppgifterna kommer inte i svårighetsordning. Betygsgränser: 15 ger säkert 3, 21 ger säkert 4, 26 ger säkert 5. Lycka till! 1

Uppgifter 1. Nedanstående figur visar noderna i ett binärt sökträd med heltal som nycklar. 12 3 23 1 7 17 31 5 20 42 a) Rita hur trädet ser ut efter inlägg av nycklarna 22, 19, 24, 18 och 15 (i den givna ordningen). (2p) 12 3 23 1 7 17 31 5 15 20 24 42 19 22 18 b) Skriv en klass Node som skall representera noderna i trädet samt en klass BST som representerar trädet. Klasserna skall innehålla nödvändiga instansvariabler och lämpliga konstruktorer. 2

Snyggast är att göra noden som en inre klass till BST-klassen. Då blir den dold för omvärlden men BST-klassen har full tillgång till den. Om man gör nodklassen som en egen självständig klass måste man ha get-metoder för dess attribut. BST-klassen behöver ingen konstruktor eftersom dess enda attribut root blir null automatiskt. public class BST { private Node root; private static class Node { private int key; private Node left; private Node right; private Node(int key, Node left, Node right) { this.key = key; this.left = left; this.right = right; c) Skriv en metod public int leaves() i klassen BST som returnerar antalet löv i trädet. (2p) Ett löv är alltså en nod som inte har några barn, public int leaves() { return leaves(root); private int leaves(node r) { if (r == null) { return 0; // inga löv else if (r.left == null && r.right == null){ return 1; // detta är ett löv else { // inte ett löv räkna på längre ner return leaves(r.left) + leaves(r.right); d) Skriv en metod void leveltraverse() i klassen BST som traverserar trädet i nivåordning och skriver ut värdet i varje nod som besöks. För trädet ovan skall alltså raden 12 3 23 1 7 17 31 5 20 42 skrivas ut. 3

Principen är att skriva en rekursiv metod som hittar allt på en viss nivå. När man har den kan man sen iterera över alla nivåer. // hjälpmetod, trädets höjd private int height(node r){ if(r == null) return 0; else return 1 + Math.max(height(r.left),height(r.right)); // fixa en angiven nivå public void leveltraverse(int n) { leveltraverse(root, n); private void leveltraverse(node r, int n) { if(r == null) return; // inget att göra if( n == 0) { // roten System.out.print(r.data + " "); else { // gå åt vänster, sedan åt höger leveltraverse(r.left, n - 1); leveltraverse(r.right, n - 1); // nu kan vi fixa allt, iterera över alla nivåer public void leveltraverse() { int n = height(); for (int i = 0; i < n; i++) leveltraverse(i); System.out.println(); Man kan också göra detta ickerekursivt, då behöver vi en kö. Algoritm: Köa rotnoden Så länge kön inte tom Ta ut första elementet i kön, skriv ut datadelen Köa vänsterbarnet följt av högerbarnet Klart. 2. Betrakta följande klasshierarki och testmetod: 4

public abstract class Animal { public String name; public final String s = "Animal"; public Animal(String name){ this.name = name; public String getname() { return name; public abstract String speak(); public class Dog extends Animal { public final String s = "Dog"; public String speak() { return getname() + ": " + s + " Woof "; public class Labrador extends Dog { public final String s = "Labrador "; public class Cat extends Animal { public final String s = "Cat"; public String speak() { return getname() + ": " + s + " Miaow "; public class Test { public static void main(string[] args) { Animal a1 = new Animal("Nisse"); System.out.println(a1.speak() + a1.s); Animal a2 = new Dog("Fido"); System.out.println(a2.speak() + a2.s); Dog a3 = new Labrador("Labbe"); System.out.println(a3.speak() + a3.s); Animal a4 = new Labrador("Lubbe"); System.out.println(a4.speak() + a4.s); Cat a5 = new Animal("Muppet"); System.out.println(a5.speak() + a5.s); Dog a6 = new Labrador("Ludde"); System.out.println(a6.speak() + a6.s); a) Det går inte att kompilera klassen Animal med dess underklasser som de är defininerade ovan, beroende på det sätt konstruktorerna är deklarerade. Förklara problemet och visa hur man ska rätta till det så att det fungerar på avsett sätt, dvs så att alla djur får ett namn när de skapas. Det går inte att kompilera Animal-hierarkin därför att det saknas konstruktorer i alla djurklasserna. Som det är nu så finns bara en parameterlös defaultkonstruktor där som anropar motsvarande parameterlösa konstruktor i Animal som saknas. Detta ger kompileringsfel. Detta gäller alldeles oavsett vad man gör i klassen Test. Vi måste alltså införa konstruktorer på något sätt. Exempelvis Public class Dog { public final String s = "Dog"; public Dog(String name) {... super(name); // anropa Animals konstruktor Detta gör också att klassen kan användas på det sätt man gör i Test Notera att det inte går att ersätta super med this.name = name; Då anropas fortfarande den icke existerande parameterlösa konstruktorn i Animal, vilket ger kompileringsfel Notera också att det går utmärkt att överskugga även final-deklarerade variabler. Man skulle kunna ta bort konstruktorn i Animal, då går det att kompilera eftersom vi då får en parameterlös defaultkonstruktor i klassen. Men då kan vi ju inte använda klassen på det sätt vi gör i Test för att namnge djuren. b) Klassen Test med sin main-metod går inte heller att kompilera. Stryk satser i 5

main-metoden som är illegala och ange sedan vad metoden skriver ut. Förklara också varför du tar bort de satser du strukit. Ta bort satserna Animal a1 = new Animal("Nisse"); System.out.println(a1.speak() + a1.s); Vi kan inte skapa objekt av typ Animal eftersom den är abstrakt Cat a5 = new Animal("Muppet"); System.out.println(a5.speak() + a5.s); Som ovan, dessutom kan inte ett objekt deklarerat som Animal tilldelas ett objekt deklarerat som en Cat. Utskrift: Fido: Dog Woof Animal Labbe: Dog Woof Dog Lubbe: Dog Woof Animal Ludde: Dog Woof Dog Notera att uttryck som a2.s binds av hur a2 är deklarerad, inte av vad a2 faktiskt är, vi får alltså Animal eftersom a2 är deklarerad som en sådan. Uttrycket a2.speak() (ett metodanrop) binds däremot av vad a2 faktiskt är, i detta fall av typen Dog. Det finns ingen speak i Labrador, alltså kan aldrig texten Labrador skrivas ut, utan det blir alltid speak i Dog för dessa och då används s i Dog. 3. Vi har följande klass som representerar en sorterad länkad lista: public class List { private Node first; private static class Node { private int value; private Node next; private Node(int value, Node next) { this.value = value; this.next = next; public List() { first = null; private List(Node n) { first = n; public String tostring() { String res = ""; for (Node n = first; n!= null; n = n.next) { res = res + n.value; if (n.next!= null) { res = res + ", "; return "{" + res + ""; private static Node insert(int k, Node n) { if (n==null k<n.value) { return new Node(k, n); else if (k>n.value) { n.next = insert(k, n.next); return n; public void insert(int k) { first = insert(k, first); a) Man skulle kunna tänka sig att implementera metoden insert på detta sätt: 6

public void insert(int k) { if (first == null first.value > k) first = new Node(k, first); else { // gör en sublista med alla noder // utom den första och lägg in i den List l = new List(first.next); l.insert(k); Förklara vad som händer och varför inte detta fungerar som tänkt. Metoden testar först om den nya noden ska in först i listan. Om det är så så läggs den in först i listan. Detta fungerar utmärkt. Annars skapas en ny lista och vi rekurserar med denna. Så småningom kommer vi att lägga in något först i denna lista. Men problemet är då att vi inte lägger in något i den ursrungliga listan utan i en annan lista, som dessutom bara är borta när vi är klara. Vår lista ändras alltså inte alls utom om vi lägger först i listan. b) Skriv en metod boolean isdisjunkt(list l) som testar om aktuell lista och listan l saknar datavärden som är lika. Om det är så ska metoden returnera true, om listorna innehåller någon nod som är lika ska false returneras. Metoden ska vara O(n), dvs linjärt beroende av listornas längd. (5p) public boolean isdisjunkt(list l){ return isdisjunkt(first, l.first); private static boolean isdisjunkt(node n1, Node n2) { if (n1 == null n2 == null) { return true; // om någon är tom så är det sant else if(n1.value == n2.value) { return false; // lika alltså falskt else if(n1.value < n2.value) { // stega fram listan som är minst return isdisjunkt(n1.next, n2); else { return isdisjunkt(n1, n2.next); 4. I bilagan finns kod som delvis implementerar en kalkylator. (Det är väsentligen samma kod som gavs till obligatorisk uppgift 5. ) Av utrymmesskäl är vissa delar som saknar betydelse för uppgiften utelämnade. a) Vi vill utöka kalkylatorn med en funktion power(x,n) som returnerar värdet av x upphöjt till n. Denna funktion har alltså två parametrar till skillnad från de övriga funktioner vi använt. Förklara hur arvshierarkin ska förändras för att införa sådana funktioner. Förklara vilka klasser som behövs och vilka ändringar i övrigt som behövs för att göra detta. Det hela ska göras på ett generellt sätt så att vi enkelt kan införa flera funktioner som har två parametrar. 7

Du behöver inte skriva någon kod för de klasser du inför, beskriv mer abstrakt hur du tänker. Vi ska alltså införa en ny typ Function med två parametrar. Den passar naturligt in i hiearkin under klassen Binary. Man skapar en hierarki som är lika som den till klassen Unary. Det betyder att vi får ett subträd för binära operatorer och ett annat för funktioner med två operander. Klassen Power görs sedan som en subklass till den senare klassen. Som en enklare lösning (fast mindre generell och därför inte så bra) kan man placera Power som en subklass direkt under Binary. Dessutom måste vi skriva den nya klasserna och förändra primary i Parsern så att den kan hantera denna funktion. Vi behöver också en ny metod i Symbolic som hanterar denna funktion på liknande sätt som övriga funktioner. b) De trigonometriska funktionerna (sin, cos... ) förutsätter att argumentet är givet i radianer. Ibland kan man ju vilja uttrycka sig i grader. För att kunna ange att man vill använda grader har kommandot set lagts in i metoden statement. Kommandot skall följas antingen av ordet degrees eller ordet radians. Exempel: Input : sin(0.5*pi) Parsed: sin(0.5*pi) Result: 1.0 Input : sin(90) Parsed: sin(90.0) Result: 0.8939966636005579 Input : set degrees Input : sin(90) Parsed: sin(90.0) Result: 1.0 Input : sin(30) Parsed: sin(30.0) Result: 0.49999999999999994 Input : set radians Input : sin(90) Parsed: sin(90.0) Result: 0.8939966636005579 Input : set nygrader *** Syntax error: Expected radians or degrees *** The error occurred at token nygrader just after token set Input : sin(0.5*pi) Parsed: sin(0.5*pi) Result: 1.0 Input : Skriv klart metoden performset() i klassen Calculator som skall se till att grader respektive radianer används enligt exemplet ovan. Skriv också de övriga kompletteringarna av koden som krävs! Tips: Grader (g) kan räknas om till radianer (r) med formeln r = g=180 8

Svårigheten i denna uppgift ligger i att överföra informationen från metoden performset i klassen Calculator till det ställe där beräkningarna faktiskt görs dvs metoderna sin och cos i klassen Symbolic. Det bästa sättet är att förse klassen Symbolic med en flagga som anger om grader eller radianer skall användas. Denna flagga sätts med en set-metod som alltså anropas från performset. Eftersom metoderna i klassen Symbolic alla är static måste såväl flaggan som dess set-metod deklareras static I Calculator: public void performset() { tokenizer.nexttoken(); if (tokenizer.gettoken().equals("radians")) { Symbolic.setRadians(true); else if (tokenizer.gettoken().equals("degrees")) { Symbolic.setRadians(false); else { throw new SyntaxException("Expected radians or degrees "); tokenizer.nexttoken(); I Symbolic private static boolean useradians = true; public static void setradians(boolean value) { useradians = value; public static Sexpr sin(sexpr operand) { if (!operand.isconstant()) { return new Sin(operand); else if (useradians) { return new Constant(Math.sin(operand.getValue())); else { return new Constant(Math.sin(operand.getValue()*Math.PI/180)); och på motsvarande sätt i cos 9