4.1 Αναζήτηση Εισαγωγή στη C++
Εισαγωγή Με την αναζήτηση εξετάζουμε το ενδεχόμενο ύπαρξης μιας συγκεκριμένης τιμής μέσα σε μία συλλογή δεδομένων (π.χ. πίνακας) Υπάρχουν διάφορες τεχνικές αναζήτησης που διαφέρουν σε δυσκολία υλοποίησης και χρόνο εκτέλεσης. Θα εξετάσουμε τη σειριακή και τη δυαδική αναζήτηση
Σειριακή Αναζήτηση Εύκολη στην υλοποίηση Ο χρόνος εκτέλεσης του αλγόριθμου είναι γραμμικός Ο(Ν) Περιγραφή αλγόριθμου Ξεκινούμε από το 1 ο στοιχείο της συλλογής δεδομένων και συγκρίνουμε το στοιχείο αναζήτησης με κάθε στοιχείο της συλλογής, μέχρι να βρούμε το στοιχείο που ψάχνουμε ή μέχρι να εξαντλήσουμε όλα τα στοιχεία της συλλογής
Υλοποίηση Συνάρτησης bool find_key(int A[],int key,int N){ int i=0; bool flag=false; while(i<n &&!flag){ if(a[i]==key) flag=true; i++; return flag;
Παράδειγμα 1 Να δημιουργήσετε το πρόγραμμα που διαβάζει τον αριθμό μητρώου και το βαθμό για 100 μαθητές από το αρχείο in.txt. Στη συνέχεια διαβάζει από το πληκτρολόγιο τον αριθμό μητρώου ενός μαθητή και αν ο μαθητής υπάρχει στο αρχείο τότε τυπώνει στην οθόνη τον βαθμό του, διαφορετικά τυπώνει «Not Found»
Παράδειγμα 1 int main(){ #include<iostream> ifstream fin("in.txt"); #include<fstream> int students[n][2]; #define N 100 int i,t,am; using namespace std; for(i=0;i<n;i++) fin>>students[i][0]>>students[i][1]; int find_key(int A[][2],int key){ cin>>am; int i=0,pos=-1; t=find_key(students,am); if(t==-1) while(i<n && pos==-1){ cout<<"not found"<<endl; if(a[i][0]==key) else pos=i; cout<<students[t][1]<<endl; i++; fin.close(); return pos; return 0;
Παράδειγμα 2 Το ΥΠΠ έχει καταγεγραμμένα τα στοιχεία (κωδικός, όνομα, τηλέφωνο, διεύθυνση) των σχολείων στο αρχείο schools.txt. Υπάρχουν το πολύ 200 σχολεία. Να γράψετε το πρόγραμμα που δέχεται τον κωδικό ενός σχολείου και τυπώνει στην οθόνη τα στοιχεία του. Σε περίπτωση που το σχολείο δεν υπάρχει τότε τυπώνει «Not found»
Παράδειγμα 2 #include<fstream> #include<iostream> #include<string> using namespace std; struct school{ int code; string st[3]; ; while(!fin.eof()){ fin>>sc[i].code; for(int j=0;j<3;j++){ fin>>sc[i].st[j]; i++; int find_sc(school sc[],int key,int N){ int pos=-1,i=0; while(i<n && pos==-1){ if(sc[i].code==key) pos=i; i++; return pos; int main(){ school sc[200]; int i=0,key,t; ifstream fin("schools.txt"); cin>>key; t=find_sc(sc,key,i); if(t==-1) cout<<"not found"<<endl; else{ cout<<sc[t].code<<endl; for(int j=0;j<3;j++) cout<<sc[t].st[j]<<endl; fin.close(); return 0;
Δυαδική Αναζήτηση (Binary Search) Η δυαδική αναζήτηση ανήκει στην κατηγορία προβλημάτων «Διαίρει και Βασίλευε» (Divide and Conquer) Είναι μία τεχνική για σχεδίαση αλγορίθμων που βασίζονται στη διάσπαση της προς επίλυση περίπτωσης σε μικρότερες υποπεριπτώσεις του ίδιου προβλήματος, στη διαδοχική και ανεξάρτητη επίλυση αυτών και στο συνδυασμό των επί μέρους λύσεων με τέτοιο τρόπο, ώστε να σχηματισθεί η λύση της αρχικής περίπτωσης.
Δυαδική Αναζήτηση (Binary Search) Στην απλούστερη μορφή της χρησιμοποιείται για να βρούμε γρήγορα μια τιμή σε έναν ταξινομημένο πίνακα Έστω ότι έχουμε ένα πίνακα μεγέθους Ν. Επιλέγουμε να ξεκινήσουμε την αναζήτηση μας από τη μέση του πίνακα. Αν δεν έχουμε πετύχει το στόχο τότε συγκρίνουμε το μεσαίο στοιχείο (Μ) με το στοιχείο που ψάχνουμε(s). Αν S<Μ τότε χρειάζεται να ψάξουμε στα στοιχεία 1 μέχρι Μ-1 Διαφορετικά θα ψάξουμε στα στοιχεία Μ+1 μέχρι Ν-1. Επαναλαμβάνουμε τα ίδια βήματα μέχρι να πετύχουμε τον στόχο μας. Έχει καλύτερο χρόνο εκτέλεσης από τη σειριακή αναζήτηση με πολυπλοκότητα log 2 N
Γραφική Απεικόνιση Έστω ότι ελέγχουμε για την ύπαρξη της τιμής 84 στον πίνακα. first middle last first middle last middle last first
Υλοποίηση Συνάρτησης bool binary_s(int A[],int key){ int first,last,middle; bool flag=false; first=0; last=n-1; while(!flag && first<=last){ middle=(first+last)/2; if(a[middle]==key){ flag=true; else if(a[middle]>key) last=middle-1; else first=middle+1; return flag;
Παράδειγμα 3 Στο αρχείο customers.txt υπάρχουν τα στοιχεία το πολύ 50,000 πελατών. Για κάθε πελάτη υπάρχουν καταχωρημένα ο αριθμός ταυτότητας, το ονοματεπώνυμο και το email. Να γράψετε το πρόγραμμα που διαβάζει τα στοιχεία και τα καταχωρεί σε έναν πίνακα και χρησιμοποιεί τη συνάρτηση find_cust για να βρει τα στοιχεία ενός πελάτη. Σε ένα αρχείο search.txt υπάρχουν οι αριθμοί ταυτότητας για τους πελάτες που ψάχνουμε. Τα στοιχεία για κάθε πελάτη που ψάχνουμε θα καταχωρούνται στο αρχείο out.txt Αν δεν υπάρχει πελάτης θα καταχωρείται ο αριθμός ταυτότητας και δίπλα το μήνυμα «Customer not found» Σημείωση: Τα στοιχεία για τον κάθε πελάτη είναι το ένα κάτω από το άλλο. Παράδειγμα 99999 John Smith smith@email.com
Παράδειγμα 3 #include<iostream> #include<fstream> #include<string> #define N 50000 using namespace std; struct customers{ ; string id; string onoma; string email; int binary_s(customers A[],string key, int n){ int first,last,middle; int pos=-1; first=0; last=n-1; while(pos==-1 && first<=last){ middle=(first+last)/2; if(a[middle].id == key){ pos=middle; else if(a[middle].id > key) last=middle-1; else first=middle+1; return pos;
Παράδειγμα 3 int main(){ while(!fsearch.eof()){ fsearch>>key; customers cust[n]; string key; int i=0,index; ifstream fcust("customers.txt"); ifstream fsearch("search.txt"); ofstream out("out.txt"); while(!fcust.eof()){ fcust >>cust[i].id; fcust >> cust[i].onoma; fcust >>cust[i].email; i++; index=binary_s(cust,key,i); if(index==-1) out<<key<<" Customer not found"<<endl; else out<<cust[index].id<<" "<<cust[index].onoma<<" "<<cust[index].email<<endl; return 0;