MartinSRB

[ОС] Припрема за Т1234 - Стипендије

May 9th, 2023
814
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.42 KB | None | 0 0
  1. /**
  2.  * Napisati C++ program koji cita podatke o studentima iz ulazne datoteke i potom
  3.  * za svakog studenta racuna prosek
  4.  *
  5.  * U ulaznoj datoteci "studenti.csv" se u svakom redu nalaze informacije o studentu:
  6.  *     Ime,Prezime,Broj indeksa,Ocene
  7.  * Pritom su ocene odvojene medjusobno zarezima.
  8.  *
  9.  * Prilikom obrade podataka o studentima, mora se proveriti format indeksa da li je validan. Ako nije, zanemariti taj unos.
  10.  * Format indeksa je:
  11.  *     [[:alpha:]][[:alnum:]]{1,2}\s[[:digit:]]{1,3}\/[[:digit:]]{4}
  12.  *
  13.  * U tri izlazne datoteke rasporediti studente u zavisnosti od proseka.
  14.  * Ukoliko je prosek > 9.00 potrebno je upisati studenta u datoteku "kandidati_stipendija.csv".
  15.  * Ukoliko je prosek > 8.00 i prosek <= 9.00 potrebno je upisati studenta u datoteku "kandidati_kredit.csv".
  16.  * U ostalim slucajevima upisati studenta u datoteku "ostali.csv".
  17.  * Format u izlaznoj datoteci treba da odgovara sledecem: Ime,Prezime,Broj_indeksa,prosek
  18.  *
  19.  * Treba napraviti jednu nit koja ce samo citati redove ulazne podatke, jednu nit
  20.  * koja ce samo pisati gotove podatke u izlazne datoteke i 10 niti radnika koji ce na osnovu redova
  21.  * iz ulazne datoteke generisati sve neophodno za ispis u izlaznu datoteku.
  22. */
  23.  
  24. #include <iostream>
  25. #include <mutex>
  26. #include <condition_variable>
  27. #include <thread>
  28. #include <vector>
  29. #include <fstream>
  30. #include <regex>
  31. #include <numeric>
  32.  
  33. using namespace std;
  34.  
  35. class Student {
  36. private:
  37.     string ime;
  38.     string prezime;
  39.     string index;
  40.     vector<int> ocene;
  41.     double prosek;
  42. public:
  43.     Student(){}
  44.     Student(string ime, string prezime, string index){
  45.         this->ime = ime;
  46.         this->prezime = prezime;
  47.         this->index = index;
  48.     }
  49.  
  50.     void setOcene(vector<int> ocene){
  51.         this->ocene = ocene;
  52.         prosek = accumulate(ocene.begin(),ocene.end(), 0.) / ocene.size();
  53.     }
  54.  
  55.     double getProsek()const{
  56.         return prosek;
  57.     }
  58.  
  59.     friend ostream& operator<<(ostream& os, Student s){
  60.         os << s.ime << "," << s.prezime << "," << s.index << "," << s.prosek;
  61.         return os;
  62.     }
  63. };
  64.  
  65. template<typename T>
  66. class InputData {
  67. private:
  68.     mutex data_mtx;
  69.     // TODO dodati polja po potrebi
  70.     bool end;
  71.     vector<T> data;
  72.     condition_variable cv;
  73.     int workers;
  74. public:
  75.     InputData(): end(false), workers(0) {
  76.         // TODO
  77.     }
  78.     void add_data(T data_element) {
  79.         // TODO
  80.         unique_lock<mutex> l(data_mtx);
  81.         data.push_back(data_element);
  82.         cv.notify_one();
  83.     }
  84.     bool remove_data(T &data_element) {
  85.         // TODO
  86.         unique_lock<mutex> l(data_mtx);
  87.         while(data.empty() && !end){
  88.             cv.wait(l);
  89.         }
  90.         if(the_end()){
  91.             return false;
  92.         }
  93.         data_element = data.back();
  94.         data.pop_back();
  95.         return true;
  96.     }
  97.  
  98.     // TODO dodati metode po potrebi
  99.     void addWorker(){
  100.         unique_lock<mutex> l(data_mtx);
  101.         ++workers;
  102.     }
  103.     void removeWorkers(){
  104.         unique_lock<mutex> l(data_mtx);
  105.         if((--workers) == 0){
  106.             end = true;
  107.             cv.notify_all();
  108.         }
  109.     }
  110.     bool the_end(){
  111.         return data.empty() && end;
  112.     }
  113. };
  114.  
  115. template<typename T>
  116. class OutputData {
  117. private:
  118.     mutex data_mtx;
  119.     // TODO dodati polja po potrebi
  120.     condition_variable cv;
  121.     int data_producers_num;
  122.     vector<T> data;
  123.     bool end;
  124. public:
  125.     OutputData(): end(false), data_producers_num(0) {}
  126.     void add_data(T data_element) {
  127.         unique_lock<mutex> l(data_mtx);
  128.         data.push_back(data_element);
  129.         cv.notify_one();
  130.     }
  131.     bool remove_data(T &data_element) {
  132.         unique_lock<mutex> l(data_mtx);
  133.         while(data.empty() && !end){
  134.             cv.wait(l);
  135.         }
  136.         if(the_end()){
  137.             return false;
  138.         }
  139.         data_element = data.back();
  140.         data.pop_back();
  141.         return true;
  142.     }
  143.  
  144.     bool the_end() {
  145.         return data.empty() && end;
  146.     }
  147.  
  148.     // TODO dodati metode po potrebi
  149.     void addWorker(){
  150.         unique_lock<mutex> l(data_mtx);
  151.         ++data_producers_num;
  152.     }
  153.  
  154.     void removeWorker(){
  155.         unique_lock<mutex> l(data_mtx);
  156.         if((--data_producers_num) == 0){
  157.             end = true;
  158.             cv.notify_all();
  159.         }
  160.     }
  161.  
  162. };
  163.  
  164. void reader(string input_file_name, InputData<string>& raw_data) {
  165.     // TODO
  166.     raw_data.addWorker();
  167.     ifstream i_file(input_file_name);
  168.     string line;
  169.     while(getline(i_file, line)){
  170.         raw_data.add_data(line);
  171.     }
  172.     i_file.close();
  173.     raw_data.removeWorkers();
  174. }
  175.  
  176. void proccessing_data(InputData<string>& raw_data, OutputData<Student>& proccessed_data){
  177.     // TODO
  178.     proccessed_data.addWorker();
  179.     regex main_r("([A-Za-z]+),([A-Za-z]+),([A-Z 0-9/]+),(.+)");
  180.     regex ocene_r(",([015-9]+)");
  181.     smatch main_match;
  182.     smatch ocene_match;
  183.     Student student;
  184.     string data_line;
  185.     vector<int> ocene;
  186.     while(raw_data.remove_data(data_line)){
  187.         if(regex_search(data_line, main_match, main_r)){
  188.             student = Student(main_match[1], main_match[2], main_match[3]);
  189.             while(regex_search(data_line, ocene_match, ocene_r)){
  190.                 ocene.push_back(stoi(ocene_match[1]));
  191.                 data_line = ocene_match.suffix();
  192.             }
  193.             student.setOcene(ocene);
  194.             proccessed_data.add_data(student);
  195.             ocene.clear();
  196.             ocene.resize(0);
  197.         } //ovde necemo nista dalje jer ako linija nije u regex formi PRESKACEMO
  198.     }
  199.     proccessed_data.removeWorker();
  200. }
  201.  
  202. void writer(OutputData<Student>& proccessed_data) {
  203.     // TODO
  204.     ofstream file_stipendije("stipendije.csv"),
  205.              file_krediti("krediti.csv"),
  206.              file_ostalo("ostalo.csv");
  207.     Student student;
  208.     bool first_stipendije = true,
  209.          first_krediti    = true,
  210.          first_ostalo     = true;
  211.     if(file_stipendije.is_open() && file_krediti.is_open() && file_ostalo.is_open()){
  212.         while(proccessed_data.remove_data(student)){
  213.             double prosek = student.getProsek();
  214.             if(prosek > 9.0){
  215.                 if(first_stipendije){
  216.                     file_stipendije << student;
  217.                     first_stipendije = false;
  218.                 }else{
  219.                     file_stipendije << endl << student;
  220.                 }
  221.             }else if(prosek > 8.0 && prosek <= 9.0){
  222.                 if(first_krediti){
  223.                     file_krediti << student;
  224.                     first_krediti = false;
  225.                 }else{
  226.                     file_krediti << endl << student;
  227.                 }
  228.             }else{
  229.                 if(first_ostalo){
  230.                     file_ostalo << student;
  231.                     first_ostalo = false;
  232.                 }else{
  233.                     file_ostalo << endl << student;
  234.                 }
  235.             }
  236.         }
  237.     }
  238.     file_stipendije.close();
  239.     file_krediti.close();
  240.     file_ostalo.close();
  241. }
  242.  
  243.  
  244. int main() {
  245.     InputData<string> raw_data;
  246.     OutputData<Student> proccessed_data;
  247.  
  248.     thread th_reader(reader, "studenti.csv", ref(raw_data));
  249.     thread th_writer(writer, ref(proccessed_data));
  250.     thread th_workers[10];
  251.  
  252.     for(auto &th: th_workers){
  253.         th = thread(proccessing_data, ref(raw_data), ref(proccessed_data));
  254.     }
  255.  
  256.     th_reader.join();
  257.     for(auto &th: th_workers) {
  258.         th.join();
  259.     }
  260.     th_writer.join();
  261.    
  262.     return 0;
  263. }
Advertisement
Add Comment
Please, Sign In to add comment