Tillämpad Programmering (ID1218) :00-12:00

Relevanta dokument
Tillämpad Programmering (ID1218) :00-13:00

Omtentamen: Tillämpad Programmering (ID1218) :00-13:00

Tentamen: Tillämpad Programmering (ID1218) :00-12:00

Tillämpad Programmering (ID1218) :00-13:00

Programmering II (ID1019) :00-17:00

Programmering II (ID1019) :00-12:00

Programmering II (ID1019) :00-12:00

Programmering II (ID1019) :00-11:00

Tillämpad programmering

Programmering II (ID1019) :00-11:00

Programmering för Språkteknologer II. Innehåll. Associativa datastrukturer. Associativa datastrukturer. Binär sökning.

Programmering II (ID1019) :00-12:00

Tommy Färnqvist, IDA, Linköpings universitet

TDIU01 - Programmering i C++, grundkurs

Tentamen Datastrukturer (DAT036/DAT037/DIT960)

TDIU01 Programmering i C++

Tentamen Programmeringsteknik II Inledning. Anmälningskod:

Tentamen i DD2387 Programsystemkonstruktion med C++

Programmering II (ID1019) :00-12:00

Föreläsning 9 Innehåll

Tentamen Datastrukturer, DAT037 (DAT036)

TDDC74 Programmering: Abstraktion och modellering Tentamen, onsdag 9 juni 2016, kl 14 18

Programmering II (ID1019)

TDIU01 - Programmering i C++, grundkurs

Programmering II (ID1019) :00-12:00

TDDC74 Programmering: Abstraktion och modellering Datortenta , kl 14-18

Tillämpad programmering

Programmering i C++ EDAF30 Dynamiska datastrukturer. EDAF30 (Föreläsning 11) HT / 34

Programmering II (ID1019) :00-13: hp

TDIU01 - Programmering i C++, grundkurs

Minnestilldelning (allokering) och frigörande (avallokering) av minne

Tentamen i TDP004 Objektorienterad Programmering Lösningsförslag

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

Programmering i C++ EDA623 Arv. EDA623 (Föreläsning 6) HT / 42

DD2387 Programsystemkonstruktion med C++ Tentamen 1 Torsdag 7 januari 2016, 14:00-18:00

Två fall: q Tom sekvens: () q Sekvens av element: (a b c) ; (sum-rec '(2 4 6)) = 12. q Första elementet uppfyller vissa villkor: (2 a b c)

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 9 Jonas Lindgren, Institutionen för Datavetenskap, LiU

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

Föreläsning 9 Innehåll

Tentamen i Objektorienterad Programmering 5p, Au, D, Fri, Pr,

Teoretisk del. Facit Tentamen TDDC kl (6) 1. (6p) "Snabba frågor" Alla svar motiveras väl.

Tentamen, EDA501/EDAA20 Programmering M MD W BK L

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

TDDC77 Objektorienterad Programmering

Datastrukturer, algoritmer och programkonstruktion (DVA104, VT 2015) Föreläsning 6

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.

Tentamen Datastrukturer (DAT036)

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

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.

TDDC76 - Programmering och Datastrukturer

Tentamen, EDAA10 Programmering i Java

Tentamen Datastrukturer (DAT036)

13 Prioritetsköer, heapar

Programmering i C++ EDA623 Dynamiska datastrukturer. EDA623 (Föreläsning 11) HT / 31

Föreläsning Datastrukturer (DAT036)

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

TDDC74 Programmering: Abstraktion och modellering Tenta, kl 14 18, 11 juni 2014

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

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

TDDC74 Programmering: Abstraktion och modellering Tentamen, lördag 27 augusti 2016, kl 8 12

Tentamen ID1004 Objektorienterad programmering October 29, 2013

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

Hitta k största bland n element. Föreläsning 13 Innehåll. Histogramproblemet

Objektorientering - Arv och polymorfi. Eric Elfving Institutionen för datavetenskap

Introduktion till arv

Tabeller. Programkonstruktion. Moment 8 Om abstrakta datatyper och binära sökträd. Implementering av tabellen. Operationer på tabellen

Tentamen TEN1 HI

Tentamen i TDP004 Objektorienterad Programmering Praktisk del

Dugga Datastrukturer (DAT036)

TDDC76 - Programmering och Datastrukturer

Lite om felhantering och Exceptions Mer om variabler och parametrar Fält (eng array) och klassen ArrayList.

Universitetet i Linköping Institutionen för datavetenskap Anders Haraldsson 2

Tentamen EDAF30 Programmering i C++

Dagens föreläsning Programmering i Lisp Fö 5

Tentamen, Algoritmer och datastrukturer

Tentamen i Algoritmer & Datastrukturer i Java

TENTAMEN CD5250. Objektorienterad programutveckling med C++, 5p. Datum: , Tid: 14:00-19:00

Lösningar Datastrukturer TDA

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

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 8 Erik Nilsson, Institutionen för Datavetenskap, LiU

Tentamen i Algoritmer & Datastrukturer i Java

Datalogi I, grundkurs med Java 10p, 2D4112, Fiktiv tentamen, svar och lösningar och extra kommentarer till vissa uppgifter 1a) Dividera förs

Tentamen i Programmering

Rekursiva algoritmer sortering sökning mönstermatchning

Tentamen Datastrukturer (DAT036)

Tentamen i Algoritmer & Datastrukturer i Java

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

Programmeringsmetodik DV1 Programkonstruktion 1. Moment 8 Om abstrakta datatyper och binära sökträd

Föreläsning 9 Datastrukturer (DAT037)

Namn: (Ifylles av student) Personnummer: (Ifylles av student) Tentamensdatum: Tid: Hjälpmedel: Inga hjälpmedel

Föreläsningsanteckningar, Introduktion till datavetenskap HT S4 Datastrukturer. Tobias Wrigstad

Tentamen i DD2387 Programsystemkonstruktion med C++

Övningsuppgifter kapitel 8

Symboliska konstanter const

Föreläsning 1 Datastrukturer (DAT037)

Föreläsning 5. Träd Binära träd Binärt sökträd som ADT Implementering av binärt sökträd Travestera binärt sökträd Sökning Insättning/borttagning

Tentamen, EDA690 Algoritmer och Datastrukturer, Helsingborg

Abstrakta datatyper. Primitiva vektorer. Deklarera en vektor

LÖSNINGSFÖRSLAG TILL Tentamen i objektorienterad programmering i C++ I

Försättsblad till skriftlig tentamen vid Linköpings Universitet

Transkript:

ID1218 Johan Montelius Tillämpad Programmering (ID1218) 2012-12-10 09:00-12:00 Förnamn: Efternamn: Regler Du får inte ha något materiel med dig förutom skrivmateriel. Mobiler etc, skall lämnas till tentamensvakten. Instruktioner Tentamen har totalt 36 poäng och skall skrivas på 3 timmar. Läs igenom hela tentamen innan du börjar. Svaren skall lämnas på dessa sidor, använd det utrymme som finns under varje uppgift för att skriva ner ditt svar. Om du inte får plats med sitt svar så kan du använda ytterligare sidor. Dessa sidor skall då vara märkta med namn och personnumer. Det skall även tydligt framgå i svaret under uppgiften att ytterligare sidor har använts. Du skall lämna in hela denna tentamen. Svar skall skrivas på svenska. 1

Betyg < 16 F 16 E 20 D 24 C 28 B 32 A Erhållna poäng Skriv inte här, detta är för rättningen. Uppgift 1 2 3 4 5 6 Σ Max 6 6 6 6 6 6 36 Poäng Totalt antal poäng: Betyg: 2

1 Funktionell Programmering[totalt 6 poäng] 1.1 Ett träd[2 poäng] Skriv en funktion update(key, Tree), som tar en nyckel och ett ordnat binärt träd, och returnerar ett nytt träd där värdet för nyckeln Key har ökats med 1. Trädet skall fortfarande vara ordnat. Om nyckeln inte finns skall en ny nod läggas till i trädet där värdet för nyckeln är 1. Vi kan representera ett träd med antingen atomen nil (det tomma trädet) eller en tupel{node, Key, Value, Left, Right}. Antag att vi kan ordna nycklar med den vanliga<operatorn. update(key, nil) -> {node, Key, 1, nil, nil}; update(key, {node, Key, V, L, R}) -> {node, Key, V+1, L, R}; update(key, {node, K, V, L, R}) when Key < K -> {node, K, V, update(key, L), R}; update(key, {node, K, V, L, R}) when Key > K -> {node, K, V, L, update(key, R)}. 3

1.2 RLE[2 poäng] Skriv en funktion rle(list) i Erlang som kompakterar en lista av atomer. Kompakteringen skall ske genom så kallad run length encoding där en obruten sekvens av identiska atomer representeras som en tuple{i, N} där I är atomen och N antalet förekomster i sekvensen. Den kompakterade versionen av listan [b,a,c,c,c,a,a,b,c] representeras som följer [{b,1}, {a, 1}, {c,3}, {a,2}, {b,1}, {c,1}] rle([]) -> []; rle([h T]) -> rle(t, H, 1). rle([], I, N) -> [{I,N}]; rle([h T], H, N) -> rle(t, H, N+1); rle([h T], I, N) -> [{I,N} rle(t, H, 1)]. 4

1.3 Två lika stora delar[2 poäng] Skriv en funktion split(list) som returnera en tuple{a, B} där A och B tillsammans innehåller alla element ur den ursprungliga listan och är så lika långa som möjligt (lika om listan har ett jämnt antal element, och en diff på 1 om den har ett ojämnt antal). Den ursprungliga listan skall bara gås igenom en gång. Du kan inte använda exempelvis length/1 för att ta reda på längden av listan. split(l) -> split(l, [], []). split([], A, B) -> {A, B}; split([h T], A, B) -> split(t, [H B], A). 5

2 Högre-ordningens funktioner[6 poäng] 2.1 map, filter och fold[2 poäng] Skriv en funktion som tar en lista med heltal och producerar: summan av de kvadrater som är jämna (lista[2,3,4] resulterar i 4+16 dvs 20). Du skall använda dig av följande högre ordningens funktioner: filter/2, map/2, foldl/3 och/eller foldr/3, se appendix för hur de anropas. Operatorn rem ger resten vid heltalsdivision ( X rem 2== 0 evalueras till true om X är ett jämnt tal). sumesqr(list) -> Squares= map(fun(x) -> X*X end, List), Even = filter(fun(x) -> X rem 2 == 0 end, Squares), foldl(fun(x,a) -> X+A end, 0, Even). 6

2.2 uppdatera ett träd[2 poäng] Skriv en funktion update(fun, Tree), som tar en funktion och ett träd och returnerar ett nytt träd som har samma struktur som det givna trädet men där varje nods värde är resultatet som fås när funktionen appliceras på det ursprungliga värdet. Antag att trädet representeras med nil för det tomma trädet och{node, Key, Value, Left, Right} för en nod med en nyckel och ett värde. update(fun, nil) -> nil; update(fun, {node, Key, Value, Left, Right}) -> {node, Key, Fun(Value), update(fun, Left), update(fun, Right)}. 7

2.3 foldr av träd[2 poäng] Givet representationen av träd i föregående uppgift, skriv en högre ordningens funktion traverse(fun, Acc, Tree) som tar en funktion, ett initialt värde och ett träd och returnerar det värde som är resultatet av att applicera funktionen på elementen i trädet och den ackumulerade parametern. Ordningen skall vara sådan att man börjar med trädets mest högra element och sedan arbetar sig mot vänster. Följande anrop Tree = {node, g, 3, {node, a, 2, nil, nil}, {node, m, 4, nil, nil}}, traverse(fun(x,a) -> [X A] end, [], Tree). skall ge resultatet Res = [2,3,4] Resultatet blir i det är fallet en lista med inorder traversering. Noter dock att vi har applicerat funktionen i omvänd ordning i.e. Fun(2, Fun(3, Fun(4,[]))). traverse(fun, Acc, nil) -> Acc; traverse(fun, Acc, {node, Key, Value, Left, Right}) -> traverse(fun, Acc, Fun(Value, traverse(fun, Acc, Right))). 8

3 Concurrency[totalt 6 poäng] 3.1 liten process[2 poäng] Skriv en funktion i Erlang som implementerar en process. Processen skall ha ett tillstånd som är en räknare och kunna ta emot följande meddelandet: {add, N} : addera N till tillståndet. {sub, N} : subtrahera N från tillståndet. open(state) -> receive {add, N} -> open(state + N); {sub, N} -> open(state - N) end. 3.2 lite större[2 poäng] Utöka processen i uppgiften ovan så att den kan hantera följande meddelanden: {read, Ref, From}: där From är en process-id från en anropande process, svara med{state, Ref, State}. open(state) -> receive : {read, Ref, From} -> From! {state, Ref, State}, open(state) end. 9

3.3 låsning[2 poäng] Pricessen skall kunna befinna sig i två olika tillstånd open som du implemeterat hittills och locked som du nu skall implementera. Detta gör vi genom att lägga till följande meddelande till open: {lock, Ref, From}: där From är en process-id från en anropande process, svara med{locked, Ref, State} och gå över i det låsta tillståndet. I det låsta tillståndet skall vi kunna hantera följande meddelande: {add, Ref, N} : addera N till tillståndet. {sub, Ref, N} : subtrahera N från tillståndet. {release, Ref}: gå över till det öppna tillståndet. Notera att vi inte skall acceptera vilket meddelanden som helst. Vi skall inte låta lura oss utan endast ta emot meddelanden som har exakt samma referens Ref som användes när vi låste processen - alla andra meddelanden skall vara kvar i meddelandekön. open(state) -> receive end. : {lock, Ref, From} -> From! {locked, Ref. State}, locked(state, Ref) locked(state, Ref) -> received {add, Ref, N} -> locked(state+n, Ref); {sub, Ref, N} -> locked(state-n, Ref); {release, Ref} -> open(state) end. 10

4 Värden, pekare och arrayer i C ++ [totalt 6 poäng] 4.1 legala uttryck[2 poäng] Vilka uttryck är legala uttryck i C ++ (som följer standarden C ++ 03 )? Svara enbart ja eller nej, alla rätt ger 2 poäng, ett avdrag för varje fel. 1. int &x; nej: vi kan inte skapa en referens utan att säga vad den skall referera till 2. int y = 3; int &x = y; ja: vi definerar en referens x och låter den referera till y 3. int y = 7; int *x = &y; ja: inget problem att ta adressen av x och det är en int 4. int x=32; int** y = &(&x) - 5; nej: vi kan inte ta adressen av en adress (inte ett l-värde) 5. int y = 7; int *x = y; nej: y är av typen int, men x har typen int* 4.2 värdet på x:[2 poäng] Givet nedanstående uttryck, vad är värdet på variabeln x? int a[5] = {3,2,1,5,4}; int x = a[2] + a[3]; Variabeln x får värdet 6 eftersom arrayer är noll-indexerade. 4.3 värdet på y:[2 poäng] Givet nedanstående uttryck, vad är värdet på variabeln y? int a[5] = {3,2,1,5,4}; int y = *(&a[3] - 2); Variabeln y får värdet 2 eftersom (&a[3] - 2) är &a[1] och *(&a[1]) är a[1] dvs 2. 11

5 Klasser och objekt[totalt 6 poäng] I följande frågor antar vi att vi inkluderar biblioteket iostream och använder dess namespace std. Vi har också definierat en klass IntCell enligt nedan. 5.1 inte riktigt som vi tänkt oss[2 poäng] Givet är följande definitiom av IntCell och en procedur swap(intcell &x, IntCell &y) som låter x och y byta värden. class IntCell { public: IntCell(int initialvalue = 0 ) { storedvalue = new int(initialvalue); } ~IntCell() { delete storedvalue} int getvalue() const { return *storedvalue; } void setvalue(int val) { *storedvalue = val;} private: int *storedvalue; }; void swap(intcell &x, IntCell &y) { IntCell tmp = IntCell(); } tmp = x; x = y; y = tmp; Vi har även ett litet testprogram som använder sig av vår swap-procedur. int test() { IntCell x(1); IntCell y(2); swap(x, y); } cout << "x = " << x.getvalue() << endl; cout << "y = " << y.getvalue() << endl; 12

int main() { test(); cout << "ok" << endl; } Allting kompilerar men redan första körningen resulterar i en crash. Vad är det som går fel? När swap anropas skapas ett temporärt objekt, tmp, som får en pekare till den int som är allokerad för x. När proceduren returnerar så avallokeras tmp. Detta kommer generera ett anrop till destruktorn IntCell vilket i sin tur kommer att göra delete på den int som tmp har en pekare till. Denna int var ju allokerad av x och borde inte alls avallokeras. Redan när vi gör anropen y.getvalue() är vi ute på hal is eftersom vi nu har en pekare till en int som vi gjort delete på. Har vi tur så överlever vi men utfallet är odefinierat. När vi returnerar från test så kommer x och y att avallokeras men y har ju då en pekare till den int som en gång allokerades för x (och som vi redan gjort delete på). Vi kan ha tur men det troliga är, som i det här fallet, att det resulterar i en crash. 13

5.2 vilka objekt modifieras[2 poäng] Givet programmet nedan, vad kommer att skrivas ut på cout och varför? Skriv en kort motivering till ditt svar. class IntCell { }; public: IntCell(int initialvalue = 0 ) { storedvalue = new int(initialvalue); } int getvalue() const { return *storedvalue; } void setvalue(int val) private: { *storedvalue = val;} int *storedvalue; int main() { IntCell a(2); IntCell b = a; IntCell c; c = b; a.setvalue(4); } cout << a.getvalue() << endl; cout << b.getvalue() << endl; cout << c.getvalue() << endl; Det kommer att skrivas ut tre stycken 4:or. Anledningen är att objekten b och c kommer att peka på samma int. När vi modifierar denna genom a.setvalue(4) så kommer alla anrop till getvalue() returnera samma sak. Observera att b inte pekar på a, inte heller pekar c på b. Objektet b har en pekare till den int som blev allokerad för a. 14

5.3 En student är också en person, eller?[2 poäng] Givet följande definitioner: class Person { string name; public: Person(const string &nn) : name(nn) {}; void print() const { cout << name; }; }; class Student : public Person { string prgm; public: Student(const string &nn, const string &cc) : Person(nn), prgm(cc) {} void print() const { Person::print(); cout << "/" << prgm; } }; void foo(const Person &p) { }; p.print(); Vad skrivs ut när vi kör programmet nedan? Varför och hur skull vi kunna ändra på beteendet? int main() { } Student jim("jim", "ICT"); foo(jim); Programmet skriver ut Jim eftersom C ++ använder statisk dispatch och proceduren foo då kommer att ta för givet att p är en Person. Om vi vill att foo vid run-time skall kunna avgöra vilket objekt den får måste vi deklarera metoden print som virtuell (mha virtual). Vi skulle också kunn ha två olika versioner av foo eler att definera den med hjälp av ett template. 15

6 Komplexitet[totalt 6 poäng] 6.1 Sökning i ordnat träd[2 poäng] Antag att vi har representerat en mängd nyckel-värde par i ett ordnat träd och har en sökfunktion som plockar fram ett värde givet en nyckel. Vilken tidskomplexitet har en sådan funktion? Svara med den asymptotiska tidskomplexiteten exempelvis O(n) där n är... Glöm inte att ange vad n är. Sökning i ett träd är O(log(n)) där n är antalet element i trädet. Att säga att sökning är O(n) där n är djupet i trädet är iofs rätt men frågan är väl då kanske hur djupet fårhåller sig till antalet element.. 6.2 Hitta rätt lista[2 poäng] Antag att vi har en representerar en mängd sekvenser som en lista av listor. Vi har en sökfunktion som letar efter en sekvens genom att traversera listan och jämföra sekvenser i listan med den sekvans som man söker efter. Jämförelsen görs genom att jämföra element för element av de två sekvenserna. Vilken tidskomplexitet har en sådan funktion? Svara med den asymptotiska tidskomplexiteten exempelvis O(n) där n är... Glöm inte att ange vad n är. Sökningen är O(n) där n=k*l, k är längden på listan och l är längden på de sekvenser vi arbetar med. Detta under förutsättning att vi kan avgöra om två element är lika i konstant tid. Att svara O(n 2 ) där n är längden på den längsta av listan (inlkuderat listan som inehåller listorna) är inte riktigt rätt, antag att sekvenserna alla är l långa, hur beter sig exekveringstiden om vi dubblerar längden på listan som håller sekvenserna? 6.3 Sudoku[totalt 2 poäng] Antag att vi har skrivit en sudokulösare som kan lösa sudokus av storlek 9x9. Vi har testkört den för ett antal sudokus och sett att den hittar en lösning grovt uppskattat en tid som är proportionell till 4 n/4 där n är antalet okända (n typiskt ligger mellan vara mellan 40 och 60). Detta motsvarar ett sökträd med förgreningsfaktor 4 (antalet val man har när man måste gissa) och djup n/4 (antalet gissningar vi gör om vi hela tiden gissar rätt). Antag att vi kan förbättra vår propagreringsalgoritm så att vi kan halvera antalet val vi har när vi måste gissa till 2 och antalet sökningar till n/8, vi kommer alltså ha svarstider som är proportionella till 2 n/8. Den mer kraftfulla algoritmen tar dock ca 1000 gånger så läng tid att köra varje gång den används, är det värt att använda den? Gör en grov uppskattning av hur körtiderna skulle ändras om vi använde den förbättrade algoritmen. Vi kommer gå från 2 n/2 till 2 n/8 antalet sökningar men varje propagering kostar en faktor 2 10. Om n är 40 till 60 så går vi från 2 20-2 30 till cirka 2 15 16

2 18. Vi vinner alltså i storleksordningn 2 5-2 12, med andra ord en rätt så bra affär. 17

Appendix Följande Erlang-funktioner kan komma till användning. map(fun, List): returnerar en lista där funktionen applicerats på varje element i den givna listan. filter(fun, List): returnerar en lista av de element i listan för vilka funktionen returnerar true. foldl(fun, Acc, List) och foldr(fun, Acc, List): returnerar en värde som fås genom att applicera funktionen på varje element i listan och ett ackumulerat värde där Acc är det initiala ackumulerade värdet. Funktionen foldr börjar med det sista elementet och foldl med det första elementet 18