A DiseaseMonitor module that allows us to record the cases of multiple diseases and export numerous statistics about them. A DiseaseMonitorLib.a file is also included, so that a static library with the modules used in the implementation can be used. A test file with a simple unit test for the implementation is included under the /tests directory.
Compile and run with:
make run
Υλοποιήστε ένα module DiseaseMonitor το οποίο θα επιτρέπει την καταγραφή κρουσμάτων από διαφορετικές ασθένειες, και την εξαγωγή στατιστικών για αυτά. Η περιγραφή των λειτουργιών υπάρχει στο include/DiseaseMonitor.h (διαβάστε το προσεκτικά!).
Για την υλοποίησή σας μπορείτε να δημιουργήσετε οποιεσδήποτε δομές δεδομένων επιθυμείτε (θα χρειαστείτε παραπάνω από μία), και να χρησιμοποιήσετε όλους τους ADTs και τις αντίστοιχες υλοποιήσεις που είδαμε στο μάθημα (αντιγράψτε ελεύθερα ό,τι θέλετε από το lecture-code).
Μοναδικοί κανόνες:
Όλες οι λειτουργίες θα πρέπει να εκτελούνται σε χρόνο το πολύ O(logn) όπου n ο συνολικός αριθμός εγγραφών στο σύστημα.
Η dm_get_records (επιστρέφει εγγραφές που πληρούν συγκεκριμένα κριτήρια) επιστρέφει πολλές εγγραφές οπότε ο χρόνος εκτέλεσής της αναγκαστικά εξαρτάται από τον αριθμό m των εγγραφών που επιστρέφονται. Πάρα ταύτα, για σταθερό m θα πρέπει να παραμένει O(logn). Δηλαδή, αν πχ αυξάνονται οι εγγραφές και κάθε φορά καλούμε την dm_get_records με κριτήρια που επιστρέφουν ακριβώς m = 10 εγγραφές, ο χρόνος εκτέλεσης θα πρέπει να αυξάνεται λογαριθμικά ως προς το .
Η dm_count_records (επιστρέφει τον αριθμο m των εγγραφών που πληρούν συγκεκριμένα κριτήρια) θα πρέπει να τρέχει σε χρόνο καλύτερο από O(m) (λύσεις O(m) δεν είναι αποδεκτές). Αυτό πχ απαγορεύει το να καλέσουμε απλά την dm_get_records και να μετρήσουμε πόσες εγγραφές επέστρεψε, χρειαζόμαστε γρηγορότερη λύση.
Από την άλλη, ο χρόνος εκτέλεσης μπορεί να εξαρτάται από τον αριθμό των διαφορετικών τιμών country, disease, date που πληρούν τα κριτήρια. Ο αριθμός αυτός είναι σε worst-case, αλλά στην πράξη θεωρούμε ότι παραμένει μικρός. Πχ μπορεί να έχουμε m = 10^6 εγγραφές, αλλά μόλις 100 διαφορετικούς συνδυασμούς country, disease, date.
Για την υλοποίηση του DiseaseMonitor.c χρησιμοποιήθηκαν:
Ένα Map που αντιστοιχίζει ids με records. Ένα Map που αντιστοιχίζει σε κάθε disease ένα Set, στο οποίο διατηρούνται χρονολογικά ταξινομημένα τα records που αναφέρονται στη disease. Ένα Map που αντιστοιχίζει σε κάθε country ένα Set, στο οποίο διατηρούνται χρονολογικά ταξινομημένα τα records που αναφέρονται στην country. Ένα Map που διατηρεί τους διάφορους συνδυασμούς disease, country, date και τους αντιστοιχίζει με το πλήθος τους. Ένα Map που αντιστοιχίζει τις διάφορες ασθένειες της χώρας που ζητείται στην dm_top_diseases() με το πλήθος των records στα οποία αυτές εμφανίζονται. Ένα Map που αντιστοιχίζει τις διάφορες ασθένειες με το πλήθος των records στα οποία αυτές εμφανίζονται, ανεξαρτήτως χώρας. Τα Set έχουν υλοποιηθεί με τη χρήση AVLTree.
Πολυπλοκότητες (όπου n οι συνολικές εγγραφές στο σύστημα):
dm_insert_record(): είναι O(logn), αφού χρησιμοποιεί αναζήτηση σε Map που είναι O(1) και insert/remove σε AVLTree που είναι O(logn). dm_remove_record(): είναι O(logn), αφού χρησιμοποιεί αναζήτηση σε Map που είναι O(1) και remove σε AVLTree που είναι O(logn). dm_get_records(): είναι O(logn), αφού χρησιμοποιεί αναζήτηση σε Map που είναι O(1), αναζήτηση σε Set που είναι O(logn) και διατρέχονται μόνο οι εγγραφές που πρέπει να επιστραφούν (το οποίο είναι επιτρεπτό από την εκφώνηση). dm_count_records(): είναι καλύτερη από O(m) (όπου m το πλήθος των εγγραφών που θα επιστραφεί), αφού διατρέχεται ένα Map που περιέχει τους συνδυασμούς αυτών των εγγραφών, οι οποίοι στην πράξη είναι σχετικά λίγοι για πολλά records. Σε κάθε συνδυασμό είναι αποθηκευμένο το πλήθος των εγγραφών του, οπότε το λαμβάνουμε σε O(1). Το linear search σε αυτούς τους συνδυασμούς είναι αποδεκτό. dm_top_diseases(): είναι O(m) (όπου m το πλήθος των εγγραφών για τη συγκεκριμένη χώρα). Σε εφαρμογές στην πράξη θεωρούμε ότι υπάρχουν παραπάνω από μία χώρες, άρα η πολυπλοκότητα δεν θα εξαρτάται από το n. Διατρέχονται, επίσης, οι διάφορες ασθένειες στο Map, αλλά στην πράξη θεωρούμε ότι έχουν πεπερασμένο πλήθος, άρα είναι O(1). Η υλοποίηση DiseaseMonitor.c περνά το αντίστοιχο test επιτυχώς και χωρίς leaks.