Προγραμματισμός Υπολογιστών με C++ ( 2012-13 ) 3η διάλεξη Ίων Ανδρουτσόπουλος http://www.aueb.gr/users/ion/ 1
Τι θα ακούσετε σήμερα Πληροφορίες για την 1η εργασία. Οι τάξεις vector, set και map. Χρήση επαναληπτών των set και map. Εισαγωγή στους δείκτες. 2
Εντοπισμός ανεπιθύμητων μηνυμάτων παραδείγματα επιθυμητών και ανεπιθύμητων μηνυμάτων + σωστές απαντήσεις 1 η εργασία εκπαίδευση προεπεξεργασία προεπεξεργασία αλγόριθμος μάθησης συνάρτηση ταξινόμησης ταξινομητής νεοεισερχόμενο μήνυμα χρήση απόφαση: επιθυμητό ή ανεπιθύμητο 3
Προεπεξεργασία μηνύματος ΑΔΤ Subject: only if you are serious... will i help you retire in 2 to 3 years! time is money so why waste my time or yours...... you have to be serious about retiring in 2 to 3 years with the money u need to live the life u always wanted yes, you have to work hard but we can help you regardless of you ' re current age or financial situation please only if you are serious ( not curious ) call the number today for a 24 hour recorded message 1-800 - 995-0796 ext. 8511 c # ed < message file = "..." category = "spam" features = "3" > < feature token = "!" id = "0" freq = "1" /> < feature token = "you" id = "7" freq = "7" /> < feature token = "money" id = "9" freq = "2" /> </ message > 4
Προεπεξεργασία επιθυμητού μηνύματος Subject: free english to spanish translation programs i am trying to compile of list of free programs to translate from the english to spanish language. i am not interested in research projects on linguistics but in " off the shelf " software. please email information to me, and i will post a summary of responses. thank you. - rick < message file = "..." category = "ham" features = "3" > < feature token = "language" id = "1" freq = "1" /> < feature token = "free" id = "3" freq = "2" /> < feature token = "linguistics" id = "5" freq = "1" /> </ message > 5
#include <vector> #include <string> #include <iostream> using namespace std; Η τάξη vector int main() { vector<string> v; // vector που θα περιέχει strings string word; while(cin >> word && word!= "stop") { v.push_back(word); // προσθήκη στο τέλος του vector for(unsigned i = 0; i < v.size(); i++) { cout << v[i] << endl; 6
#include <set> #include <string> #include <fstream> #include <iostream> using namespace std; Η τάξη set int main() { Αν η λέξη υπάρχει ifstream infile("input.txt"); ήδη στο s, δεν ξαναπροστίθεται. set<string> s; string word; while(infile>> word) { s.insert(word); cin >> word; if( s.find(word)!= s.end( ) ) { // Ελέγχει αν το s περιέχει cout << "yes" << endl; // το word. 7
Χρήση επαναλήπτη (iterator) με set #include <set>... int main() { ifstream infile("input.txt"); set<string> s; string word; while(infile >> word) { s.insert(word); Ή σκέτο «iterator», αν θέλουμε να κάνουμε αλλαγές με τον επαναλήπτη. To «const_iterator» δείχνει ότι ο επαναλήπτης δεν θα χρησιμοποιηθεί για να τροποποιήσουμε το σύνολο. set<string>::const_iterator setiterator; for(setiterator = s.begin(); setiterator!= s.end(); setiterator++) { cout << *setiterator << endl; Με τον αστερίσκο αναφερόμαστε στα περιεχόμενα της θέσης όπου δείχνει ο επαναλήπτης. 8
Απλούστερα σε C++11 χωρίς επαναλήπτη #include <set>... int main() { ifstream infile("input.txt"); set<string> s; string word; while(infile >> word) { s.insert(word); for(string member : s) { cout << s << endl; Η μεταβλητή member παίρνει διαδοχικά όλες τις τιμές του συνόλου s. Αντί for(string member : s) μπορούμε να γράψουμε for(auto member :s). Η C++11 καταλαβαίνει αυτόματα τον τύπο της member (ξέρει ότι το s περιέχει string). 9
Η τάξη map #include <iostream> #include <string> #include <map> using namespace std; int main() { map<string, unsigned> mymap; mymap["hi"] = 1; // Δημιουργείται νέο ζεύγος ( hi, 1). mymap["hi"] = 2; // To ζεύγος γίνεται ( hi, 2). mymap["there"] = 3; // Δημιουργείται νέο ζεύγος ( there, 3). mymap["there"]++; // Το ( there, 3) γίνεται ( there, 4). mymap["test"]++; // Nέο ζεύγος ( test, 0), γίνεται ( test, 1). cout << mymap["hi"] << mymap["there"] << mymap["test"] << endl; // Τυπώνει 2, 4, 1. 10
Χρήση επαναλήπτη με map #include <map>... int main() { map<string, unsigned> wordoccurrences; string word; ifstream infile("input.txt"); // Μετράω πόσες φορές εμφανίζεται η κάθε λέξη: while(infile >> word) { wordoccurrences[word]++; map<string, unsigned>::const_iterator mapiterator; for(mapiterator = wordoccurrences.begin(); mapiterator!= wordoccurrences.end(); mapiterator++) { cout << (*mapiterator).first << ": " << (*mapiterator).second << endl; C++11: for(auto m : wordoccurrences) { cout << m.first << ": " << m.second << endl; 11
Δείκτες Το «0x» υποδηλώνει δεκαεξαδική παράσταση αριθμού int i = 5; 0x85AF 5 cout << i; // Τυπώνει 5. cout << &i; // Τυπώνει τη διεύθυνση της i: 0x85AF. i int* p = &i; // Δείκτης σε ακέραιο. cout << p; // Τυπώνει 0x85AF. cout << *p; // Τυπώνει 5. 0x85B3 p 0x85AF *p = 6; // Αλλάζει το i. cout << i; // Τυπώνει 6. p i int j = 10; p = &j; // Τώρα το p δείχνει στο j. cout << *p; // Τυπώνει 10. p j 12
new και delete float* fp = new float; // Δημιουργία νέου χώρου // αποθήκευσης για τιμές float. *fp = 2.0F; // Αποθήκευση τιμής float. cout << fp << endl // Τυπώνει 0xFF10. << *fp << endl; // Τυπώνει 2. delete fp; // Αποδέσμευση του χώρου στον οποίο δείχνει o fp. Σε αυτή την περίπτωση ο δείκτης δεν δείχνει στο χώρο μιας άλλης μεταβλητής, αλλά σε χώρο που δημιουργήσαμε με new. 0xFF10 0x859A 2.0 fp 0xFF10 13
Δυναμική καταχώριση μνήμης void myfun() { float f = 1.0F; // Στατική καταχώριση μνήμης.( στοίβα (χώρος μεταβλητών στη // float* fp = new float; // Δυναμική καταχώριση μνήμης.( σωρό (με new, από το // *fp = 2.0F; cout << f << endl << *fp << endl; delete fp; // Αποδέσμευση του χώρου στον οποίο δείχνει ο fp. Ο χώρος της τοπικής μεταβλητής f αποδεσμεύεται αυτόματα κατά την έξοδο από τη myfun. Ο δυναμικά δεσμευμένος χώρος παραμένει μέχρι να αποδεσμευτεί με delete. Χωρίς τα κατάλληλα delete, έχουμε διαρροή μνήμης. 14
Χώρος στη στοίβα Κλήση της myfun από άλλη συνάρτηση. Προστίθενται στη στοίβα: σημείο επιστροφής (διεύθυνση στον κώδικα της άλλης συνάρτησης όπου έγινε η κλήση της myfun), τοπικές μεταβλητές της myfun Κλήση συνάρτησης f μέσα από τη myfun (ή αναδρομική κλήση της myfun). Προστίθενται στη στοίβα: σημείο επιστροφής (διεύθυνση στον κώδικα της myfun όπου έγινε η κλήση της f), τοπικές μεταβλητές της f κλπ. Ολοκλήρωση συνάρτησης: Αφαιρούνται τα αντίστοιχα στοιχεία από την κορυφή της στοίβας (άρα εξαφανίζονται οι τοπικές μεταβλητές της συνάρτησης που ολοκληρώθηκε), γυρίζουμε στη δ/ση επιστροφής κλπ. myfun:δ/ση επιστροφής, τοπικές μεταβλητές, f: δ/ση επιστροφής, τοπικές μεταβλητές, myfun:δ/ση επιστροφής, τοπικές μεταβλητές,
Χώρος στη στοίβα και το σωρό σωρός myfun:δ/ση επιστροφής, τοπικές μεταβλητές int f: int* fp: 2.0 0xFF10 fp = new int; 0xFF10: 2.0 Ο δείκτης fp είναι τοπική μεταβλητή (στη στοίβα). Ο χώρος μνήμης που περιέχει την τιμή του (τη δ/ση στην οποία δείχνει) ελευθερώνεται αυτόματα στο τέλος της myfun. Ο χώρος μνήμης στον οποίο δείχνει ο fp έχει δημιουργηθεί με new (στο σωρό). Ο χώρος αυτός εξακολουθεί να είναι δεσμευμένος και μετά την ολοκλήρωση της myfun, μέχρι να ελευθερωθεί με delete.