Ασκήσεις Επανάληψης Οι πιο κάτω ασκήσεις παρατίθενται µαζί µε σχολιασµό και τη λύση τους. Ορισµένες είναι αυτοσχέδιες ενώ άλλες είναι ασκήσεις παρµένες από τις σηµειώσεις Εργαστηρίου του κ. Οικονόµου. Η πρώτη άσκηση είναι πλήρως λυµένη ενώ από στις υπόλοιπες µπορεί να απουσιάζει η τυχόν ανάγνωση πίνακα από το πληκτρολόγιο (αφού είναι ίδιος κώδικας για όλες τις ασκήσεις). Με! επισηµαίνονται σχόλια µέσα στον κώδικα της άσκησης. Ο τρόπος αυτός σχολιασµού είναι ΜΟΝΟ για Fortran 90 ενώ στη Fortran 77 γίνεται µε c στην πρώτη στήλη µόνο. Άσκηση 1 Να γραφεί πρόγραµµα το οποίο αφού διαβάσει τα στοιχεία και τις διαστάσεις (τις οποίες και θα ελέγξει) δύο (2) πραγµατικών πινάκων δύο (2) διαστάσεων από το πληκτρολόγιο a(.,.) και b(.,.), να δηµιουργεί έναν πίνακα µε ίδιες διαστάσεις c(.,.) µε στοιχεία τα µέγιστα ή ίσα µεταξύ των στοιχείων των a(.,.) και b(.,.) στα αντίστοιχα µονά αθροίσµατα των συντεταγµένων θέσης του καθενός και τα ελάχιστα ή ίσα µεταξύ των στοιχείων των a(.,.) και b(.,.) στα αντίστοιχα ζυγά αθροίσµατα των συντεταγµένων θέσης του καθενός (από τα a(.,.) και b(.,.)). Ο πίνακας c να τυπώνεται σωστά ώστε να φαίνεται σαν πίνακας (να τυπώνεται και κατά γραµµές και κατά στήλες). Μετά τον ορισµό και διαστασιοποίηση της άσκησης θα πρέπει να υπάρχουν µέσα σε βρόχο επανάληψης (do) οι κατάλληλες συνθήκες οι οποίες θα εξετάζουν αν οι δείκτες των πινάκων βρίσκονται σε µονά αθροίσµατα θέσεων ή ζυγά. Ανάλογα µε το if, υπολογίζει το µέγιστο ή το ελάχιστο, άρα υπάρχει if µέσα σε if. real a(100,100), b(100,100), c(100,100)! ιαστασιοποίηση 10 print *, 'dose diastasi pinakwn' read *, e! µια διάσταση για τετραγωνικού πίνακες, θα µπορούσαν να είναι δύο. if ((e.lt.0).or.(e.gt.100).or.(e.ne.int(e))) then print *, 'try again!' goto 10! Ανάγνωση πινάκων print *, 'diabasma pinaka a' do i=1,e do j=1,e print *, 'diabasma a',i,j read *, a(i,j) print *, 'diabasma pinaka b' do i=1,e do j=1,e print *, 'diabasma b',i,j read *, b(i,j)! κύριο σώµα άσκησης ρ. Γ. Π. Οικονόµου / Μ. Γεωργουδάκης / Γ. Κεραµίδας 1
do i=1,e do j=1,e if ((i+j)/2.ne.int((i+j)/2)) then! ελέγχει αν το άθροισµα i+j είναι άρτια ή περιττά µε σύγκριση µε το! ακέραιο µέρος του αθροίσµατός τους /2. if (a(i,j).ge.b(i,j)) then! ελέγχει ποιο στοιχείο ανάµεσα στους δύο πίνακες είναι µεγαλύτερο c(i,j)=a(i,j) else c(i,j)=b(i,j) elseif (a(i,j).le.b(i,j)) then c(i,j)=a(i,j) else c(i,j)=b(i,j)! εκτύπωση πινάκων κατά γραµµές do i=1,e print *, (c(i,j), j=1,e)! εκτύπωση πινάκων κατά στήλες do j=1,e print *, (c(i,j), i=1,e) stop Άσκηση 2 Να γραφεί πρόγραµµα στη γλώσσα προγραµµατισµού Fortran το οποίο να διαβάζει από το πληκτρολόγιο τα στοιχεία ενός τετραγωνικού πίνακα πραγµατικών αριθµών (3, 3). Κατόπιν, να υπολογίζει το άθροισµα των στοιχείων για κάθε γραµµή, στήλη και την κεντρική διαγώνιο και να τα τυπώνει στο τέλος κάθε γραµµής, στο τέλος κάθε στήλης και αµέσως µετά το τέλος της κεντρικής διαγωνίου. Μια σχετικά δύσκολη άσκηση όπου χρησιµοποιούνται βοηθητικοί πίνακες ενώ ο πίνακας Β δηµιουργείται στο τέλος. real a(100,100), gr(100), st(100), b(100,100) print *,'dwse stoixeio',i,j read *, a(i,j) print *,'upologismos mo grammwn' gr(i)=gr(i)+a(i,j) if (i.eq.j) then ρ. Γ. Π. Οικονόµου / Μ. Γεωργουδάκης / Γ. Κεραµίδας 2
sd=sd+a(i,j) print *,'upologismos mo stilwn' st(j)=st(j)+a(i,j)! ηµιουργία του πίνακα Β do i=1,4 do j=1,4 b(i,j)=a(i,j) if (j.eq.4) then m=m+1 b(i,j)=gr(m) if (i.eq.4) then n=n+1 b(i,j)=st(n) if ((i.eq.4).and.(j.eq.4))then b(i,j)=sd c ypologismos megistou stoixeiou amax = a(1,1) if (amax.lt.a(i,j)) then amax = a(i,j) print *, 'megisto einai ',amax do i=1,4 print *,(b(i,j),j=1,4) stop ρ. Γ. Π. Οικονόµου / Μ. Γεωργουδάκης / Γ. Κεραµίδας 3
Άσκηση 3 Να γραφεί πρόγραµµα το οποίο να ορίζει πίνακα χαρακτήρων α(3) µήκους 10 και να διαβάζει τα στοιχεία του από το πληκτρολόγιο. Στη συνέχεια να µετατραπούν και να αποθηκευτούν οι κωδικοί ASCII του κάθε χαρακτήρα του κάθε στοιχείου σε πίνακα Β(3,10) Η άσκηση αυτή χρησιµοποιεί τον τελεστή επιλογής αλφαριθµητικού µέσα σε αλφαριθµητικό (substring σε string) π.χ. να επιλέξει το sta µέσα στο Kosta. Ο τελεστής αυτός είναι ιδιαίτερα χρήσιµος για να εντοπίσουµε (µε if) αν υπάρχει ένα string σε ένα πίνακα ακόµα και αν δεν εµφανίζεται µε τη µορφή αυτή ακριβώς. Στη συγκεκριµένη περίπτωση επιλέγεται ο κάθε χαρακτήρας ξεχωριστά. character a(3) *10, buffer *10, c*1 integer b(3,10)! Γέµισµα πίνακα print *,"dose keimeno gia 8esh",i read *, a(i)! κυρίως σώµα άσκησης! για το κάθε στοιχείο του πίνακα do j=1,10! για το κάθε χαρακτήρα του κάθε στοιχείου του πίνακα buffer = a(i)! µεταφέρουµε ένα στοιχείο του πίνακα σε βοηθητική µεταβλητή c = buffer(j:j)! παίρνουµε τον κάθε χαρακτήρα χωριστά, γίνεται επίσης και έτσι: c=a(i)(j:j) b(i,j) = iachar(c) print *, (b(i,j),j=1,10) Άσκηση 4 Να γραφεί πρόγραµµα το οποίο να ορίζει και να διαβάζει έναν πίνακα λογικών τιµών α(3,3) από το πληκτρολόγιο και στη συνέχεια να τυπώνει τον αριθµό των true στοιχείων της κυρίας διαγωνίου ενώ να τυπώνει στην οθόνη το αποτέλεσµα της λογικής πράξης a(1,1).and. a(2,2).and. a(3,3) Το µόνο που αξίζει να προσεχθεί είναι ότι ο έλεγχος µε if σε λογικές τιµές γίνεται µόνο µε την πιο κάτω σύνταξη του if η οποία ελέγχει αν είναι αληθές ή όχι. Το αν είναι false µπορεί να ελεγχθεί ΜΟΝΟ έµµεσα. logical a(3,3),x x=.false. print *, 'dose stoixeio a(',i,',',j,')' read *, a(i,j) ρ. Γ. Π. Οικονόµου / Μ. Γεωργουδάκης / Γ. Κεραµίδας 4
do i =1,3 if (a(i,i))then s=s+1 x=a(1,1).and.a(2,2).and.a(3,3) print *,'Synolo true stoixeiwn:',s print *,'Apotelesma logikou KAI diagwniou:',x Άσκηση 5 Να γραφεί πρόγραµµα το οποίο θα ορίζει ένα (1) πίνακα Α(3, 3) πραγµατικών και ένα (1) Β(3, 3) λογικών αριθµών και θα διαβάζει τα στοιχεία του πίνακα Α(3, 3) από το πληκτρολόγιο. Στη συνέχεια να αντιστοιχεί στον πίνακα Β(3, 3) αληθή (true) ή ψευδή (false) τιµή ανάλογα µε το αν το αντίστοιχο στοιχείο του πίνακα Α(i, j) είναι µεγαλύτερο ή όχι από το τουλάχιστον 50% του γινοµένου των δεικτών i, j της αντίστοιχης θέσης. Τέλος, να εκτυπώνει τους δύο πίνακες Η άσκηση αυτή, από παλαιότερο θέµα εξετάσεων είναι ιδιαίτερα απλή καθώς χρησιµοποιεί µόνο µια συνθήκη if µέσα σε βρόγχο για να δώσει, ανάλογα µε το αποτέλεσµα της if τιµές σε έναν πίνακα B. Στο πνεύµα αυτής της άσκησης είναι πολλά θέµατα εξετάσεων. real a(3,3) logical b(3,3)! diabasma pinaka print *, "Dose stoixeio: a(",i,j,")" read *, a(i,j)! kuriws askhsh, elegxoyme ena-ena ta stoixeia if (a(i,j)>0.5*i*j) then!elegxos sun8hkhs an to stoixeio einai > tou 50% tou ginomenou deiktwn i,j) b(i,j)=.true.!de xreiazomaste else gia.false. ka8ws e3 orismou oles oi times tou b einai false prin paroun kapoia timi!ektupwsh pinaka a print *, (a(i,j),j=1,3) print *, (" ",j=1,3)! proairetiko, na afhsei mia grammh kenh!ektupwsh pinaka b ρ. Γ. Π. Οικονόµου / Μ. Γεωργουδάκης / Γ. Κεραµίδας 5
print *, (b(i,j),j=1,3) stop Άσκηση 6 Να γραφεί πρόγραµµα το οποίο να διαβάζει έναν αριθµό (ακέραιο) από το πληκτρολόγιο και να βγάζει σχετικό µήνυµα αν ο αριθµός είναι πρώτος ή όχι. Στη συνέχει να ρωτάει το χρήση αν θέλει να δώσει άλλο αριθµό και ανάλογα µε την απάντηση να επαναλαµβάνεται αλλιώς να τερµατίζει Οι πρώτοι αριθµοί έχουν πολλές εφαρµογές, µεταξύ άλλων στην κρυπτογραφία. Πρώτος αριθµός είναι αυτός ο οποίος διαιρείται µόνο µε τον εαυτό του και τη µονάδα. Άρα αν έχουµε έναν αριθµό x και εξετάσουµε όλους τους αριθµούς από το 2 µέχρι το x-1 αν διαιρούν το x και δε βρεθεί κανένας, τότε ο x είναι πρώτος. Στην αρχή αυτή βασίζεται η λύση της άσκησης. Η λύση αυτή, υπάρχουν και άλλες, µπορεί να εφαρµοστεί ακόµα και αν εξετάζουµε πίνακες µε αριθµούς. integer a character(1) c 5 print *, "Dose stoixeio: a" read *, a do i=2,a-1!elegxoume an diaireitai me kapoion ari8mo ektos apo to 1 kai ton eauto tou if (mod(a,i)==0) then!an bre8ei estw kai enas akeraios diaireths,den einai prwtos opote bgainei apo ton brogxo print *, "den einai prwtos" goto 10 print *, "einai prwtos"!de xreiazomaste else, einai opws h askhsh sugkrishs 2 pinakwn 10 print *, "Na to 3anakanoume? Pata Y gia epanalipsi,otidipote allo gia termatismo" read *, c if (c=="y".or.c=="y") then!na labei upopsi tou oti mporei na einai mikro 'h kefalaio goto 5!phgaine sthn arxh!de xreiazetai else, 8a termatisei an den ikanopoih8ei to if,phgainontas amesws sto stop stop ρ. Γ. Π. Οικονόµου / Μ. Γεωργουδάκης / Γ. Κεραµίδας 6
Άσκηση 7 Να γραφεί πρόγραµµα το οποίο να διαβάζει τα στοιχεία ενός πίνακα χαρακτήρων Α από το πληκτρολόγιο και στη συνέχεια να τους ταξινοµεί σε αλφαβητική σειρά µε βάση το πρώτο γράµµα του κάθε στοιχείου. Η ταξινόµηση στοιχείων ενός πίνακα ορίζεται ως εξής : οθέντων των στοιχείων ενός πίνακα α(1),,α(2).α(ν) η ταξινόµηση συνίσταται στη µετάθεση της θέσης των στοιχείων ώστε τα στοιχεία να πάνε από το µικρότερο προς το µεγαλύτερο (αύξουσα σειρά) ή ανάποδα (φθίνουσα σειρά). Υπάρχουν πολλοί αλγόριθµοι ταξινόµησης αλλά εµείς θα ασχοληθούµε µόνο µε τη µέθοδο της ευθείας ανταλλαγής ή µέθοδο της φυσαλίδας (bubble sort). Για να κατανοήσουµε τη λειτουργία του αλγορίθµου πρέπει να φανταστούµε τα στοιχεία του πίνακα που θέλουµε να ταξινοµήσουµε σαν φυσαλίδες η µία τοποθετηµένη κάτω από την άλλη. Η τιµή που αντιστοιχεί σε κάθε στοιχείο του πίνακα ας φανταστούµε ότι συµβολίζει το βάρος κάθε φυσαλίδας. Προφανώς οι πιο ελαφρές φυσαλίδες έχουν την τάση να ανεβαίνουν γρηγορότερα προς τα πάνω. Η µέθοδος ταξινόµησης στην πράξη γίνεται ως εξής : Ξεκινώντας από την τελευταία φυσαλίδα (στοιχείο) κάνουµε διαδοχικές συγκρίσεις των στοιχείων ανά δύο. Αν η κατώτερη τιµή είναι µικρότερη από την από πάνω της τότε γίνεται αντιµετάθεση των στοιχείων αυτών. Η διαδικασία αυτή συνεχίζεται µέχρι να φτάσουµε στο πρώτο στοιχείο. Εκτελώντας για πρώτη φορά αυτή τη διαδικασία (1ο πέρασµα) έχουµε σίγουρα τοποθετήσει στην πρώτη θέση το στοιχείο µε την µικρότερη τιµή. Στη συνέχεια επαναλαµβάνουµε τη διαδικασία. Αν θεωρήσουµε ότι έχουµε Ν στοιχεία πίνακα προς ταξινόµηση, είναι φανερό ότι στο δεύτερο πέρασµα Ν-2 συγκρίσεις στοιχείων (αφού ξέρω πως το µικρότερο ήδη είναι τοποθετηµένο στην πιο πάνω θέση). Η ίδια διαδικασία συνεχίζεται µέχρι να ταξινοµηθούν όλα τα στοιχεία του πίνακα (η διαδικασία θα επαναληφθεί Ν-1 φορές). PROGRAM BUBBLE_SORT CHARASTER (*10) A(100), TEMP! DIASTASIOPOISI PINAKA PRINT *, DOSE NEO ARITHMO POLEON 10 READ *, G IF ((G <= 0).OR.(G > 100).OR.(G /= int(g))) THEN PRINT *, DOSE NEO ARITHMO POLEON GOTO 10 ENDIF 100 STOP END! ARXIKOPOIHSH PINAKA DO I = 1, G PRINT *, DOSE TO ONOMA TIS POLIS, I READ *, A(I) ENDDO! EFARMOGH TOY ALGORITHMOY TAKSINOMISIS! ME BASI TO PROTO GRAMMA KATHE POLIS DO I = 2, G DO J = G, I, -1 IF (A(J-1)(1:1) > A(J-1)(1:1)) THEN TEMP = A(J) A(J) = A(J-1) A(J-1) = TEMP ENDIF ENDDO ENDDO ρ. Γ. Π. Οικονόµου / Μ. Γεωργουδάκης / Γ. Κεραµίδας 7
Άσκηση 8 Να γραφεί πρόγραµµα το οποίο να διαβάζει ένα κείµενο µέχρι 100 χαρακτήρες καθώς και µια λέξη µέχρι 20 χαρακτήρες. Στη συνέχεια να αναζητά τη λέξη αυτή στο αρχικό κείµενο και αν βρεθεί, εµφανίζει τη θέση (σε πιο χαρακτήρα δηλαδή) τη βρήκε µε τη µορφή αριθµού. Ο αλγόριθµος για τη λύση αυτής της άσκησης έχει δύο στάδια: στο πρώτο πρέπει να γνωρίζουµε το ακριβές µέγεθος της λέξης που αναζητούµε ενώ στο δεύτερο στάδιο κάνουµε την αναζήτηση. Πρέπει να υπολογίσουµε το µέγεθος της προς αναζήτηση λέξης καθώς το µέγεθος 20 είναι ενδεικτικό και δείχνει µέγιστο δυνατό και όχι το πραγµατικό. Το πραγµατικό µέγεθος θα χρησιµοποιηθεί στο 2 ο βήµα. Στην απάντηση που θα δίνει το πρόγραµµά µας θα περιέχει τη θέση (π.χ. 78) στην οποία θα απαντάται ο πρώτος χαρακτήρας της αναζητούµενης λέξης. Με αντίστοιχο τρόπο δουλεύουν και οι αναζητήσεις σε εµπορικά λογισµικά όπως το Ms Word, Mozilla, κλπ.