ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΥΠΡΟΥ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ ΕΠΛ 035: οµές εδοµένων και Αλγόριθµοι για Ηλεκτρολόγους Μηχανικούς και Μηχανικούς Υπολογιστών Ακαδηµαϊκό έτος 2010 2011, Χειµερινό εξάµηνο Λύσεις Ασκήσεων Επανάληψης Ενδιάµεσης Εξέτασης Κεφάλαιο 1: Εισαγωγή ( ιάλεξη 1) 1. Τι είναι η µαθηµατική µοντελοποίηση και ποια τα στάδια της? ιαδικασία κατά την οποία δηµιουργούµε µια µαθηµατική παρουσίαση ενός προβλήµατος έτσι ώστε να το κατανοήσουµε καλύτερα. Στάδια: Περιγραφή προβλήµατος Ορισµός δεδοµένων Ορισµός επιθυµητών αποτελεσµάτων Ορισµός της πιθανής (εφικτής) λύσης του Κεφάλαιο 2: Αφηρηµένοι Τύποι εδοµένων ( ιάλεξη 1) 1. Να υλοποιηθεί προγραµµατιστικά µια δοµή (στατική δέσµευση µνήµης) η οποία να παριστάνει ένα φοιτητή και να περιέχει συγκεκριµένα τα εξής πεδία: i. Name ii. Surame iii. Age iv. Sex v. Date of Birth Να υλοποιηθεί επίσης η συνάρτηση mai() η οποία να χρησιµοποιεί την δοµή, να ορίζει/αρχικοποιεί τα στοιχεία/πεδία ενός φοιτητή και να τα τυπώνει. #iclude <stdio.h> typedef struct{ char ame[10];
char surame[10]; it age; char sex[6]; char date_of_birth[10]; Studet; it mai(){ Studet s; strcpy(s.ame, "Adrew"); strcpy(s.surame, "Thomso"); s.age = 22; strcpy(s.sex, "Male"); strcpy(s.date_of_birth, "22/11/1988"); pritf("name: %s\", s.ame); pritf("surame: %s\", s.surame); pritf("age: %d\", s.age); pritf("sex: %s\", s.sex); pritf("date of Birth: %s", s.date_of_birth); 2. Ας υποθέσουµε ότι έχουµε την παρακάτω δήλωση δοµής: typedef struct{ char a[12]; it b; it c3; typos_egrafis; typos_egrafis egr; Ας υποθέσουµε ότι ένας ακέραιος αποθηκεύεται σε µια λέξη µνήµης και τρεις χαρακτήρες σε µια λέξη µνήµης. Αν τώρα δώσουµε τις εξής τιµές στο κάθε στοιχείο (a = abcdefghijkl ; b = 11; c3 = 12), να υπολογίσετε την διεύθυνση(egr.c3) και να υλοποιήσετε (παραστήσετε γραφικά) την δοµή καταγράφοντας τις διευθύνσεις όλων των µελών της. διεύθυνση (egr.c3) = διεύθυνση (egr.a) + 4 + 1 = 0 + 5 = 5 b = 0 egr.a egr.b egr.c3 b b+1 b+2 b+3 b+4 b+5 b+6 3. ίνεται ο εξής αραιός πίνακας i/j 0 1 2 3
0 1 1 2 0 1 2 6 0 0 2 0 5 3 3 3 1 7 0 8 Να αποθηκευθεί ανά τριάδες της µορφής (i ; j ; τιµή).
Τιµή δείκτη i 0 j 1 Τιµή 2 0 4 4 11 1 0 0 1 2 0 2 2 3 1 0 2 4 1 1-1 5 1 2 6 6 2 1 5 7 2 2 3 8 2 3-3 9 3 0-1 10 3 1 7 11 3 3 8 Κεφάλαιο 3: Πολυπλοκότητα Αλγορίθµων ( ιάλεξη 2-3) 1. Αποδείξτε ότι ο χρόνος εκτέλεσης των ακόλουθων συναρτήσεων έχει ως εξής: 3 4 α) 2 + + + 1 είναι O ) β) 6 2είναι O () ( 4 Να δώσετε και την επαλήθευση για καθεµία από τις πιο πάνω συναρτήσεις. α) Πρέπει να δείξουµε ότι υπάρχει c > 0, 0 1 έτσι ώστε, 4 + + + 1 c * => + + + c 4 4 4 4 2 2 1 2 1 1 => + 1+ + c => Για c = 5, 0 = 1 η παραπάνω ανισότητα ικανοποιείτε, εποµένως η συνάρτηση T ( ) = 2 + + + 1είναι O ( 4 ). Επαλήθευση: (c = 5, = 1) (c = 5, = 2) (c = 5, = 3) 2 4 + + + 1 c * => 5 5 2 4 + + + 1 c * => 35 80 2 4 + + + 1 c * => 139 405
β) Πρέπει να δείξουµε ότι υπάρχει c > 0, 0 1 έτσι ώστε, 6 + 2 c * => 6 + 2 c => 6 + 2 c => Για c = 8, 0 = 1 η παραπάνω ανισότητα ικανοποιείτε, εποµένως η συνάρτηση T ( ) = 6 2 είναι O (). Επαλήθευση: (c = 8, = 1) 6 2 c * => 4 8 (c = 8, = 2) 6 2 c * => 10 16 (c = 8, = 3) 6 2 c * => 16 24 2. ώστε το χρόνο εκτέλεσης χείριστης περίπτωσης (µε σύντοµη επεξήγηση) των πιο κάτω προγραµµάτων σαν συνάρτηση του (Big Oh): 1. it sum=0; for(i=0; i<; i++){ sum++; for(j=1;j<; j++){ sum=sum+j; 2. it sum=0; while(i<){ sum = sum +2; for(it j = 0; j < ; j++){ sum++; i++; 3. it sum=0; for(it i = 0; i < 6*; i++){ for( it j = 1; j < * ; j++) sum++; 1. First loop is:, Secod loop is: -1 => +-1=2-1 (drop costats Ιδιότητες BigO otatio) => O() 2. Outer loop is:, Ier loop is: => * => O(^2) 3. Outer loop is: 6, Ier loop is: (*)-1 => 6*(^2-1) = 6^3-6 (drop lower terms ad costats Ιδιότητες BigO otatio) => O(^3)
Κεφάλαιο 4: Συµβολοσειρές ( ιάλεξη 4) 1. ίνονται τα ακόλουθα προγράµµατα a και b. Ποια είναι τα αποτελέσµατα που παίρνουµε από την εκτέλεση των εντολών εκτύπωσης; a. it mai(){ char s1[] = "Hello World"; char s2[11] = ; b. it mai(){ strcpy(b, &a[3]); pritf("%s\", b); pritf("%d\", strle(b)); strcat(a, b); pritf("%s\", a); pritf("%d", strle(a)); char s1[11] = "Cat"; char s2[12] = "Cut"; pritf("%d\", strcmp(s1, s2)); strcat(s1, s2); pritf("%s\", s1); pritf("%s\", s2); pritf("%d", strcmp(s1, s2)); a. lo World 8 Hello Worldlo World 19 b. -20 CatCut Cut -20 2. Ποια από τις ακόλουθες συνθήκες θα είχε ως αποτέλεσµα να καλεστεί η συνάρτηση dosomethig µόνο αν οι συµβολοσειρές a και b ήταν ίσες; a. if (strcmp(a,b)) dosomethig(); b. if (strcmp(a,b)==0) dosomethig();
c. if (a==b) dosomethig (); d. if (a[]==b[]) dosomethig (); if (strcmp(a,b)==0) dosomethig(); 3. Έχοντας υπόψη τις πιο κάτω δηλώσεις: char s1[10], s2[20]; char saturday[9]= Saturday ; char suday[7]= Suday ; εξηγήστε τι γίνεται µε την εκτέλεση των πιο κάτω εντολών: a. strcpy(s1, & suday[3]); pritf("%s\", s1); b. pritf("%d\", strle(saturday)); c. strcpy(s2, suday); pritf("%s\", s2); d. strcat(s2, saturday); pritf("%s\", s2); a. day b. 8 c. Suday d. SudaySaturday 4. ίνεται µια συµβολοσειρά ame[10]= Joatha ; Γράψτε µια συνάρτηση που θα τυπώνει τη συµβολοσειρά αυτή αντίστροφα. ηλαδή θα τύπωνε στην έξοδο: ahtaoj Πρότυπο συνάρτησης: void reverse_prit(char ame[]); void reverse_prit(char ame [ ]){ it i, ; = strle(ame); char reverse[]; for(i=0; i<; i++){ reverse[i] = ame[-i-1]; reverse[]= \0 ; pritf( %s, reverse);
Κεφάλαιο 5: είκτες και Πίνακες ( ιάλεξη 5-6) Να υλοποιήσετε τη συνάρτηση mai() και µία συνάρτηση η οποία µε δεδοµένο εισόδου ακέραιο i, επιστρέφει το όνοµα της i-οστής ηπείρου. Για οποιοδήποτε άλλο ακέραιο να επιστρέφει οτι δεν υπάρχει. Πρότυπο συνάρτησης: char *getcotiet(char *cotiets[], it i) Hit: char *cotiets[]={"does ot exist", "Europe", "America", "Africa", "Australia", "Asia"; #iclude <stdio.h> char *getcotiet(char *cotiets[], it i){ if (i < 1 i > 5) retur cotiets[0]; else retur cotiets[i]; it mai() { char *cotiets[]={"does ot exist", "Europe", "America", "Africa", "Australia", "Asia"; pritf("%s", getcotiet(cotiets, 3)); retur 0; Κεφάλαιο 6: οµές και Ενώσεις ( ιάλεξη 7) Να υλοποιήσετε µια δοµή στοίβας µε στατική δεύσµευση µνήµης και να υλοποιήσετε συνάρτηση η οποία θα υλοποιεί την ίδια λειτουργία µε την συνάρτηση Decimal2Biary (Κεφάλαιο 8 Άσκηση 1) αλλά θα είναι µη αναδροµική και θα κάνει χρήση της στοίβας. Πρότυπο συνάρτησης: void stackdecimal2biary(it umber) void stackdecimal2biary(it umber){ STACK *S; it result, mod; it x; MakeEmpty(S); result=a/2; mod=a%2; while(result!=0){ push(s,mod); mod=result%2;
result=result/2; push(s,mod); while (S->size >=0){ pritf( %d, S->list[S->size-1]; S-Size--; Κεφάλαιο 7: Memory Allocatio (malloc) ( ιάλεξη 8) 1. Ποιο σύνολο εντολών είναι ορθότερο όσο αφορά την δυναµική δεύσµευση µνήµης και γιατί? a. it *ump; ump = (it *) malloc(4); *ump = 17; free(ump); b. it *ump; ump = (it *) malloc(sizeof(it)); *ump = 17; free(ump); c. it *ump; ump = (it *) malloc(sizeof(20)); *ump = 17; free(ump); Το (b) καθώς η εντολή malloc(sizeof(it)) δεσµεύει µνήµη για την αποθήκευση ενός ακεραίου και επιστρέφει ένα δείκτη (δηλαδή τη διεύθυνση) του χώρου µνήµης που δέσµευσε. Γιατί? => Portability: Αν κάποια πλατφόρµα χρησιµοποιεί 2 Bytes για αναπαράσταση ακεραίων τότε το πρόγραµµα µας εξακολουθεί να είναι σωστό! Κεφάλαιο 8: Αναδροµή ( ιάλεξη 9) 1. Να υλοποιήσετε µια αναδροµική συνάρτηση η οποία να εκτυπώνει την δυαδική αναπαράσταση ενός ακέραιου θετικού αριθµού που δίδεται ως παράµετρος της συνάρτησης. Πρότυπο συνάρτησης: void Decimal2Biary(it umber) it2biary(16) τυπώνει στην οθόνη 10000 it2biary(7) τυπώνει στην οθόνη 111 it2biary(69) τυπώνει στην οθόνη 1000101 Η δυαδική μορφή ενός αριθμού, π.χ. 6, μπορεί να βρεθεί με τον ακόλουθο τρόπο, αν διαβάσετε τα υπόλοιπα από κάτω προς τα πάνω: 6:2 => Πηλίκο: 3, Υπόλοιπο:0 3:2 => Πηλίκο: 1, Υπόλοιπο:1
1:2 => Πηλίκο:0, Υπόλοιπο:1 6=110 102 void Decimal2Biary(it umber){ it result, modulo; result = umber/2; modulo = umber%2; if(result!= 0) Decimal2Biary(result); pritf("%d", modulo); Κεφάλαιο 9: Αφηρηµένοι Τύποι εδοµένων (ΑΤ ), Λίστες, ΑΤ Στοίβα και Ουρά ( ιάλεξη 10) 1. Ευθύγραμμη Απλά Συνδεδεμένη Λίστα: A) Ορίστε τη δομή μιας ευθύγραμμης απλά συνδεδεμένης λίστας που δημιουργείται με στατική δέσμευση μνήμης και θα περιέχει ακέραιους αριθμούς. B) Γράψετε μια μέθοδο που θα προσθέτει τα στοιχεία μιας συνδεδεμένης λίστας με τη χρήση της δομής στατικής μνήμης και θα επιστρέφει το συνολικό άθροισμα τους. Πρότυπο συνάρτησης: it additio(list *L) A) typedef struct { it list[max]; it size; LIST; B)it additio (List *L){ it i, sum=0; for(i=0;i>l->size;i++){ sum=sum+l->list[i]; retur sum; Κεφάλαιο 10: Στοίβες ( ιάλεξη 11) 1. Δίνεται η υλοποίηση μερικών πράξεων του ΑΤΔ στοίβας. Να ορίσετε τη δομή της στοίβας, να υλοποιήσετε της συναρτήσεις Push ad Top και να ορίσετε τις αναγκαίες μεταβλητές, ώστε η συνάρτηση Push να προσθέτει το στοιχείο που εισάγεται και να επιστρέφει κάθε φορά το νέο άθροισμα.
void MakeEmpty(Stack *S){ S->Legth = 0; it IsEmpty(Stack *S){ retur (S->Legth == 0); void Pop(Stack *S){ if (!IsEmpty(S)) (S->Legth)--; #defie size 5 it sum = 0; typedef struct { it list[size]; it Legth; Stack; void MakeEmpty(Stack *S){ S->Legth = 0; it Push(it x, Stack *S){ if ((S->Legth) < size) { S->list[S->Legth]= x; (S->Legth)++; sum = sum + x; retur sum; retur sum; it IsEmpty(Stack *S){ retur (S->Legth == 0); void Pop(Stack *S){ if (!IsEmpty(S)) (S->Legth)--; it Top(Stack *S){
if (!IsEmpty(S)) retur S->list[(S->Legth)-1]; Κεφάλαιο 11: Λίστες ( ιάλεξη 12) 1. Θεωρήστε πως έχουμε μια ευθύγραμμη απλά συνδεδεμένη λίστα (με δυναμική δέσμευση μνήμης) που κάθε κόμβος της περιέχει έναν ακέραιο αριθμό. Θεωρήστε ακόμα πως η λίστα είναι ταξινομημένη ώστε οι αριθμοί των κόμβων να πηγαίνουν από τον μικρότερο ως το μεγαλύτερο. Γράψτε μια μέθοδο που θα αφαιρεί από τη λίστα σας τους κόμβους με τους αριθμούς που επαναλαμβάνονται. Για παράδειγμα, αν η λίστα σας περιείχε τους κόμβους με αριθμούς: 1, 3, 5, 5, 5, 6, 7, 7, 9, 10 η συνάρτηση σας θα αφαιρούσε τους κόμβους με τα επαναλαμβανόμενα στοιχεία και θα είχαμε την εξής λίστα: 1, 3, 5, 6, 7, 9, 10. Δίνεται η δομή της ευθύγραμμης απλά συνδεδεμένης λίστας (με δυναμική δέσμευση μνήμης) η οποία να ακολουθηθεί στην υλοποίηση: typedef struct ode { it data; struct ode *ext; NODE; typedef struct stack { NODE *head; it size; STACK; void RemoveDuplicates(NODE *head) { NODE *curret = head; if (curret == NULL) retur;//αν η λίστα είναι άδεια µην κάνεις κάτι while(curret->ext!= NULL) { // Συγκρίνω τον τρέχων κόµβο µε τον επόµενο if (curret->data == curret->ext->data) { NODE *fixpoiter = curret->ext->ext; free(curret->ext); curret->ext = fixpoiter; // Αλλιώς αν δεν είναι οι ίδιοι αριθµοί else { curret = curret->ext;//προχώρα στο επόµενο