• No results found

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

N/A
N/A
Protected

Academic year: 2022

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

Copied!
8
0
0

Loading.... (view fulltext now)

Full text

(1)

Data- och Programstrukturer 7,5 högskolepoäng

Provmoment: Tentamen Ladokkod: NDP011

Tentamen ges för: Systemarkitektprogrammet Namn:

(Ifylles av student) Personnummer:

(Ifylles av student)

Tentamensdatum: 2014-06-04 Tid: 09.00 – 13.00 Hjälpmedel:

Inga hjälpmedel

Totalt antal poäng på tentamen: 45 poäng För att få respektive betyg krävs:

G >= 22 VG >= 34

Allmänna anvisningar:

 Numrera sidorna samt börja varje ny uppgift på nytt blad.

 Skriv personnummer på försättsblad och alla inlämnade sidor.

 Var tydliga, kortfattade och konkreta i era svar.

 Skriv tydligt (oläsligt = fel)!

 På programmeringsuppgifterna är principen viktigare än syntaxen.

 Poängavdrag kan ges för onödigt komplicerade eller ostrukturerade lösningar.

 Kommandon från bibliotek (även Roberts) får normalt användas fritt. Om du är osäker skriv ner vad kommandot förväntas göra.

 Inkluderingar behöver aldrig anges om det inte framgår av frågan.

Rättningstiden är som längst tre veckor

Viktigt! Glöm inte att skriva namn på alla blad du lämnar in.

Lycka till!

Ansvarig lärare: Anders Gidenstam Karl Jansson Telefonnummer: 033 435 4214 033 435 4399

(2)

2 1. Definiera och förklara följande:

a)

Lastfaktor är ett begrepp som används i kontexten av en hashtabell. Definiera vad lastfaktorn för en hashtabell är och Förklara hur den kan påverkar hashtabellen positivt och/eller negativt.

(2p) b)

Definiera de grundläggande delar och steg som krävs för att skapa en rekursiv funktion.

(1p) c)

Ett binärt sökträd är beroende av att trädet är balanserat för att upprätthålla en god tidskomplexitet. Stämmer detta också för en hög (eng. heap) eftersom denna också har en trädstruktur? Förklara varför eller varför inte trädbalans också är relevant för högar.

(1p)

(3)

3

2. Spelet Nim går ut på att plocka 1-3 mynt ifrån en stapel av mynt och undvika att vara den som tvingas plocka upp det sista myntet. En AI till spelet kan implementeras rekursivt med följande funktioner:

#define NOGOODMOVE -1

#define MAXTAKE 3

int findGoodMove(int nCoins){

int nTaken;

for(nTaken=1;nTaken<=MAXTAKE; nTaken++){

if(IsBadPosition(nCoins-nTaken)) return nTaken;

}

return NOGOODMOVE;

}

bool IsBadPosition(int nCoins){

if(nCoins==1) return true;

return(findGoodMove(nCoins) == NoGoodMove);

}

int chooseComputerMove(int nCoins){

int nTaken;

nTaken=findGoodMove(nCoins);

if(nTaken==NOGOODMOVE) nTaken=1;

return nTaken;

}

Visa i ord och bild hur följande anrop till chooseComputerMove beräknas:

chooseComputerMove(4);

En lämplig nivå är att visa vilka funktionsanrop som sker, deras argument samt returvärden.

(3p)

(4)

4 3. En nod i en labyrint definieras på följande sätt:

typedef struct mazNode{

mazNode connections[4];

bool visited;

bool exitNode;

} *mazNode;

Om en viss koppling (connections[x]) är en vägg så definieras detta med en NULL-pekare.

Skriv en rekursiv funktion som hittar en exit-nod givet en start-nod med följande funktionsprototyp:

mazNode findExit(mazNode node);

Om ingen exit-nod kan hittas skall NULL returneras. Fältet visited i mazNode skall användas för att undvika onödiga rekursiva anrop.

Ni behöver inte definiera en labyrint, enbart funktionen för att söka i en. Ni får använda hjälpfunktioner och liknande, problemet går dock att lösa med endast en rekursiv funktion.

(7p)

(5)

5 4. Betrakta följande rekursiva funktion:

int BinarySearch(string key, string array[],int low, int high) {

int mid, cmp;

if (low > high) return (-1);

mid = (low + high) / 2;

cmp = StringCompare(key, array[mid]);

if (cmp == 0) return (mid);

if (cmp < 0) {

return (BinarySearch(key, array, low, mid - 1));

} else {

return (BinarySearch(key, array, mid + 1, high));

} }

a)

Funktionen ovan är svans-rekursiv (eng. tail-recursive). Definiera vad som menas med att en rekursiv funktion är svans-rekursiv och Förklara vilka fördelar detta medför för kompilatorn.

(3p) b)

Beskriv i en mening den rekursiva idén bakom den ovanstående funktionen.

(1p) c)

Ange tidskomplexiteten (i form av ett Ordo-uttryck) för BinarySearch med avseende på N där N är antalet element i arrayen som sökningen utförs på.

(2p)

(6)

6

5. En symboltabell (eng. dictionary/map) är en abstrakt samlingsdatatyp (ADT) med (bland annat) operationerna

void Insert(symtabADT table, string key, void *value) Sätter in angivet nyckel, värde par (key, value) i symboltabellen. Om nyckeln redan finns så uppdateras det associerade värdet till value.

void* Lookup(symtabADT table, string key)

Slår upp nyckeln (key) i symboltabellen och returnerar värdet som hör ihop med den eller konstanten NOT_FOUND om värdet inte finns.

a)

Förklara i ord och bild hur man kan implementera en symboltabell med ovanstående två operationer med en hashtabell (eng. hash table) som växer vid behov. Ange och motivera även respektive operations tidskomplexitet (worst-case) uttryckt i antalet element i symboltabellen, N.

(3p) b)

Förklara i ord och bild hur man kan implementera en symboltabell med ovanstående två operationer med ett balanserat binärt sökträd (eng. balanced binary search tree).

Ange och motivera även respektive operations tidskomplexitet (worst-case) uttryckt i antalet element i symboltabellen, N.

(3p) Tips a) och b): En före och efter bild av hur datastrukturen ser ut i minnet med

förklaring av ej uppenbara förändringar är en lagom nivå för att visa hur en operation fungerar i uppgift a) och b), kod behövs inte där.

c)

Ange en typedeklaration i C för symtabCDT och eventuella hjälpstrukturer som behövs för en symboltabell implementerad som en hashtabell som växer vid behov i C.

(2p) d)

Implementera funktionen

void Insert(symtabADT table, string key, void *value) för en symboltabell implementerad som en hashtabell i C.

Du kan anta att den interna funktionen

int Hash(string s, int nBuckets);

beräknar hashkoden (mellan 0 och nBuckets - 1) för nyckelsträngen s.

Var noggrann med avseende på specialfall och minneshantering.

(5p)

(7)

7

6. En kalkylapplikation skall hantera beräkning av godtyckliga heltalsuttryck beskrivna av grammatiken

E -> T1 + E E -> T1 – E E -> T1 T1 -> T2 * T T1 -> T2 / T T1 -> T2 T2 -> (E) T2 -> integer

Ett exempel på heltalsuttryck är ”(1 + 7) * 3 + 1” som evaluerar till 25.

En modul har skapats för att implementera en abstrakt datatyp expADT för att representera abstrakta syntaxträd för heltalsuttryck.

typedef enum { ConstantType, CompoundType } exptypeT;

typedef struct expCDT *expADT;

// Konstruktorfunktioner

expADT NewConstantExp(int i);

expADT NewCompoundExp(char op, expADT lhs, expADT rhs);

// Selektorfunktioner

exptypeT ExpType(expADT exp);

int ExpConstant(expADT exp);

char ExpOperation(expADT exp);

expADT ExpLHS(expADT exp);

expADT ExpRHS(expADT exp);

a)

Föreslå en konkret representation för värden av typ expCDT i form av en

typdefinition i C för en struct av formen tagged union som passar med gränssnittet ovan.

(4p)

(8)

8 b)

Implementera funktionen

int evalExp(expADT exp);

som beräknar heltalsvärdet av ett abstrakt syntaxträd för ett heltalsuttryck enligt ovan.

Funktionen skall arbeta mot gränssnittet för expADT utan kännedom om den faktiska implementationen.

(4p)

c)

En modul för att parsa en sekvens av token till ett abstrakt syntaxträd innehåller följande parser-funktioner:

expADT ReadE(scannerADT scanner);

expADT ReadT1(scannerADT scanner);

expADT ReadT2(scannerADT scanner);

som tar hand om respektive symbol med motsvarande namn i grammatiken ovan.

Din uppgift är att implementera funktionen expADT ReadE(scannerADT scanner);

som skall arbeta mot gränssnittet för expADT utan kännedom om den faktiska implementationen. Om ett syntaxfel upptäcks skall funktionen

void Error(string msg) anropas vilken antas avbryta programmet. Du skall också anta att de andra funktionerna (readT1 och readT2) är färdiga och kan användas vid behov.

(4p)

scannerADT stöder (bl.a.) följande operationer:

string ReadToken(scannerADT scanner);

bool MoreTokensExist(scannerADT scanner);

void SaveToken(scannerADT scanner, string token);

References

Related documents

Innan taxiresorna till och från skolan beställs, skall Protector kontaktas för bekräftelse. Efter bekräftelse från Protector kan beställning av

Älgskyttebanan skall vara upptagen i general- planen för länets älgskyttebanor. Prövning i varje

FÖR ATT LAGA DITT HJÄLPMEDEL RING PERSONEN DU FICK DITT HJÄLPMEDEL AV ELLER RING HJÄLPMEDELSCENTER. DU KAN BEHÖVA BETALA OM HJÄLPMEDLET

Enligt lag om färdtjänst (SFS 1997:736) kan färdtjänst beviljas när du är folkbokförd i Ale kommun och du på grund av ett funktionshinder av varaktig karaktär inte

Kriterier: Kan förskrivas till patienter med kognitiva funktionsnedsättningar som stöd vid utförande av dagliga livets aktiviteter och för att möjliggöra ökad

Om du behöver hjälp att beräkna hur många förpackningar du ska förskriva eller hur många uttag som är rimligt för en viss tidsperiod finns hjälp i systemet att beräkna

”Bedömningen av den verksamhetsförlagda utbildningen sker enligt ett systematiserat och validerat bedömningsformulär.” (Kursplan, C46E50 v.. • På första sidan kryssas den

(a) Vilket eller vilka av följande påståenden gäller för