ΣΧΟΛΗ ΠΟΛΙΤΙΚΩΝ ΜΗΧΑΝΙΚΩΝ ΕΜΠ ΜΕΘΟΔΟΙ ΕΠΙΛΥΣΗΣ ΜΕ Η/Υ 8 η ΕΝΟΤΗΤΑ Συμβολοσειρές Δομές Ν.Δ. Λαγαρός Μ. Φραγκιαδάκης Α. Στάμος
Άδεια Χρήσης Το παρόν εκπαιδευτικό υλικό υπόκειται σε άδειες Χρήσης Creative Commons. για εκπαιδευτικό υλικό, όπως εικόνες, που υπόκειται σε άδεια χρήσης άλλου τύπου, αυτή πρέπει να αναφέρεται ρητώς. 115
Περιεχόμενα 1) Συμβολοσειρές (συνέχεια) 2) Εγγραφή σε αρχεία με τυχαία διαμόρφωση 3) Δομές 4) Εφαρμογές 116
Συμβολοσειρές Έστω οι αλφαριθμητικές μεταβλητές (ή αλλιώς συμβολοσειρές ή string) FirstName = Giwrgos LastName = Georgiou οι μεταβλητές μπορούν να ενωθούν με την εντολή: BestStudentName = [FirstName LastName] Το αποτέλεμα της παραπάνω εντολής είναι: GiwrgosGeorgiou Για να διαχωρίσουμε όνομα και επίθετο με κενό, μπορούμε να γράψουμε: BestStudentName = [FirstName ' ' LastName] ή διαφορετικά BestStudentName2 = [ The best student is ' FirstName ' ' LastName] Η παραπάνω συνένωση ονομάζεται concatenation και είναι μία πολύ χρήσιμη πράξη στο Matlab. 117
Συμβολοσειρές Έστω η παρακάτω αλφαριθμητική μεταβλητή: StudentName = Giwrgos Georgiou, born in 1992 Για να αποθηκεύσουμε σε τρείς διαφορετικές μεταβλητές (α) το όνομα, (β) το επίθετο και (γ) την ηλικία του κ. Γιώργου Γεωργίου, χρησιμοποιούμε τις εντολές: FirstName = StudentName(1:7) LastName = StudentName(9:16) Age = 2015 str2num(studentname(26:end)) Παρατηρήσεις: χρειαζόμαστε την εντολή str2num για να μετατρέψουμε μία συμβολοσειρά σε αριθμό, το αντίθετο επιτυγχάνεται με την εντολή num2str. οι εντολες length(studentname) και size(studentname) μας δίνουν το μήκος του string, δηλαδή: >> length(studentname) ans = 30 >> size(studentname) ans = 1 30 118
Συμβολοσειρές StudentName = Giwrgos Georgiou, born in 1992 Εαν θέλουμε το πρόγραμμα να αναγνωρίζει μόνο του τις διάφορες μεταβλητές, μπορούμε να χρησιμοποιήσουμε την εντολή find. koma = find(studentname==,') % θέσεις του, μέσα στο string keno = find(studentname== ' ') % θέσεις των κενών μέσα στο string FirstName = StudentName(1:keno(1)-1) LastName = StudentName(keno(1)+1:koma-1) Age = 2015 str2num(studentname(keno(4)+1:end)) Η εντολή find ψάχνει μέσα στο string για να βρεί τις θέσεις που υπάρχει το αντίστοιχο κομμάτι κειμένου (π.χ. κόμα ή κενό). Mία νέα αλφαριθμητική μεταβλητή, μικρότερου μήκους, πρκύπτει, έαν πάρουμε ένα τμήμα της αρχικής μεταβλητής: >> tmp = StudentName(10:20) tmp = eorgiou, bo 119
Συμβολοσειρές Έστω τα string: tline1 = 6.63100 3.50700 1.62800 1.105 tline2 = 6.63100, 3.50700, 1.62800, 1.105 Η εντολή A = sscanf(str, format) μπορεί να χρησιμοποιηθεί για να διαβάσουμε δεδομένα από μία συμβολοσειρά. Παραδείγματα: >> v1 = sscanf(tline1,'%f') v1 = 6.6310 3.5070 1.6280 1.1050 Χρήσιμα παραδείγματα θα βρείτε στο help, (γραφοντας την εντολή doc sscanf) Για το 2 ο string tline2 μπορούμε να χρησιμοποιήσουμε την παρακάτω διαμόρφωση: >> v2 = sscanf(tline2, '%f, %f, %f, %f ) v2 = 6.6310 3.5070 1.6280 1.1050 120
Ανάγνωση αρχείων τυχαίας διαμόρφωσης Έστω το αρχείο seismos.txt με περιεχόμενο: time step: 0.02, number of steps: 3000 6.631000e+00, 3.507000e+00, 1.628000e+00, 1.105000e+00, 4.260000e-01 2.390000e-01, -2.680000e-01, -1.836000e+00, -1.490000e+00, 1.413000e+00-1.058000e+00, 1.669000e+00, 1.167600e+01, 1.149800e+01, -2.920000e-01-1.671800e+01, -1.228200e+01, -3.280000e+00, -1.202900e+01, -6.913000e+00 Θέλουμε: (α) να διαβάσουμε όλες τις τιμές του αρχείου και να τις αποθηκεύσουμε στο διάνυσμα acc (β) να διαβάσουμε το βήμα και το μήκος της καταγραφής και να τα αποθηκεύσουμε στις μεταβλητές dt και nsteps. 121
Ανάγνωση αρχείων τυχαίας διαμόρφωσης (συνέχεια) Το αρχείο seismos.txt διαβάζεται με τον παρακάτω κώδικα: fid =fopen('seismos.txt'); tline = fgetl(fid); tmp = sscanf(tline,'time step: %f, number of steps: %f'); dt = tmp(1); nsteps = tmp(2); count=0; while feof(fid) == 0 tline = fgetl(fid); tmp = sscanf(tline,'%f, %f, %f, %f, %f') acc(count+1:count+5) = tmp; count = count + 5; end fclose(fid) plot((1:length(acc))*dt,acc,'b.-') 122
Ανάγνωση αρχείων τυχαίας διαμόρφωσης (συνέχεια) αναλυτικά ο κώδικας: ανοίγουμε το αρχείο που θα διαβάσουμε, το Matlab εφεξής θα το αναγνωρίζει ως fid fid =fopen('seismos.txt'); εντολή fgetl διαβάζει ως μία συμβολοσειρά την πρώτη γραμμή του αρχείου tline = fgetl(fid); με την εντολή sscanf διαβάζουμε τα περιεχόμενα της 1 ης γραμμής tmp = sscanf(tline,'time step: %f, number of steps: %f'); dt = tmp(1); nsteps = tmp(2); 123
Ανάγνωση αρχείων τυχαίας διαμόρφωσης (συνέχεια) count = 0; Λέμε στο πρόγραμμα να κάνει επαναλήψεις μέχρι να βρεί το τέλος του αρχείου fid (εντολή feof(fid) == 0) while feof(fid) == 0 διαβάζουμε κάθε γραμμή μία-μία (αφού βρισκόμαστε μέσα σε ένα for loop) tline = fgetl(fid); εξάγουμε τα αριθμητικά δεδομένα και τα αποθηκεύουμε στο 5x1 διάνυσμα tmp tmp = sscanf(tline,'%f, %f, %f, %f, %f'); αποθηκεύουμε τα αριθμητικά δεδομένα στο διάνυσμα acc acc(count+1:count+5) = tmp; προσαυξάνουμε τον μετρητή count κατά 5 (τόσες τιμές διαβάσαμε) count = count + 5; end Δεν ξεχνάμε στο τέλος να «κλείσουμε» το αρχείo fid (ώστε να μπορεί να το διαβάσει κάποιο άλλο πρόγραμμα). fclose(fid) 124
δομές / structures Οι δομές (structures) επιτρέπουν την ομαδοποίηση δεδομένων σε μία μεταβλητή Έχουν την μορφή μεταβλητή.πεδίο1.πεδιο2 Μπορούν να έχουν διαστάσεις μητρώων Τα πεδία μπορούν να έχουν ανομοιογενείς τιμές (κείμενο, αριθμοί, μητρώα, κλπ) Παράδειγμα: id = 1; student(id).firstname = 'Alexander'; student(id).lastname = 'Georgiou'; student(id).fathername = 'Petros'; student(id).afm = '0692345678'; Student(id).school = 'civil engineering'; student(id).heightweight = [167 70]; student(id).haircolor = 'red'; 125
δομές / structures (συνέχεια) student(id).grades.statics = '4'; student(id).grades.hydraulics = '6'; student(id).grades.steel1 = '3'; student(id).grades.concrete1 = '8'; id = 2; student(id).firstname = Viky student(id).lastname = Antoniou ; 126
δομές / structures Η προηγούμενη δήλωση παράγει το αποτέλεσμα: >> student student = firstname: 'Alexander' lastname: 'Georgiou' fathername: 'Petros' afm: '0692345678' heightweight: [167 70] haircolor: 'red' grades: [1x1 struct] >> student.grades ans = Statics: '4' Hydraulics: '6' Steel1: '3' Concrete1: '8' 127
δομές / structures Χρήσιμες εντολές: Προσθήκη νέου πεδίου (το όνομα του οποίου μας είναι γνωστό ως μεταβλητή) >> fieldname = 'newfield' >> student(id).fieldname = 67 Επιστρέφει πίνακα αλφαριθμητικών μεταβλητών με όλα τα πεδία >> nam = fieldnames(student) Επιστρέφει την τιμή 1 εαν υπάρχει το πεδίο και 0 διαφορετικά >> ii = isfield(student, firstname ) Επιστρέφει την τιμή 1 εαν είναι δομή και 0 διαφορετικά >> ii = isstruct(student) Αφαιρεί κάποιο πεδίο από την μεταβλητή >> ii = rmfield(student, firstname ) 128
Αλγεβρικές πράξεις μητρώων (επανάληψη) Το Matlab μπορεί πολύ εύκολα να χρησιμοποιηθεί για την επίλυση γραμμικών (και όχι μόνο!) συστημάτων, Έστω το σύστημα: 6x 12y 4z 70 7x 2y 3z 5 2x 8y 9z 64 Για την επίλυση απλά γράφουμε το σύστημα στην μορφή AX = B X=(A -1 )B A = [6,12,4;7,-2,3;2,8,-9] B = [70;5;64] X = A^(-1)*B X = 3.0000 5.0000-2.0000 129
Χρηματοδότηση Το παρόν εκπαιδευτικό υλικό έχει αναπτυχθεί στα Πλαίσια του εκπαιδευτικού έργου του διδάσκοντα. Το έργο «Ανοιχτά Ακαδημαϊκά Μαθήματα Ε.Μ.Π.» έχει χρηματοδοτήσει μόνο την αναδιαμόρφωση του εκπαιδευτικού υλικού. Το έργο υλοποιείται στο πλαίσιο του Επιχειρησιακού Προγράμματος «Εκπαίδευση και Δια Βίου Μάθηση» και συγχρηματοδοτείται από την Ευρωπαϊκή Ένωση. 130