MartinSRB

[ОС] Припрема за Т1234 - Скијалишта

May 9th, 2023
949
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.40 KB | None | 0 0
  1. /**
  2.  * Napisati C++ program koji iz ulazne datoteke cita podatke o temperaturi u toku vikenda sa ski
  3.  * staza na Kopaoniku, Zlatiboru i Jahorini i odredjuje koji dani i na kojoj planini su idealni
  4.  * za skijanje a koji nisu. Neki idealni opseg temperature za skijanje je od -5 do 3 stepena.
  5.  *
  6.  * Za svaku od planina postoji posebna datoteka cije ime se sastoji od imena planine i prosirenja
  7.  * (ekstenzije) ".txt". U svakoj pojedinacnoj datoteci se u jednom redu nalaze podaci za jedan dan.
  8.  * Jedan red sadrzi redom ime_dana, datum, i potom izmerene temperature. Temperatura se meri na
  9.  * svakih sat vremena, pocevsi od 8 ujutru, do 8 uvece. Svi podaci su odvojeni razmakom.
  10.  *
  11.  * Izgled jednog reda iz ulaznih datoteka "Kopaonik.txt" "Zlatibor.txt" "Jahorina.txt"
  12.  *
  13.  *     subota 01.02.  -15 -13 -10 -8 -3 0 -2 -3 2 2 -5 -7 -3
  14.  *
  15.  * Treba za svaki dan pronaci najnizu i najvisu dnevnu temperaturu. Ukoliko minimalna i maksimalna
  16.  * temperatura upadaju u navedeni opseg, treba informacije za taj dan ispisati u datoteku
  17.  * "idealno.txt", u suprotnom u datoteku "lose.txt".
  18.  *
  19.  * Ispis u izlaznu datoteku treba da prati format:
  20.  *     <ime_planine> [<ime_dana> <datum>] <min. temp.> >> <maks. temp.>
  21.  *
  22.  * Primer ispisa u bilo kojoj od izlaznih datoteka "idealno.txt", "lose.txt":
  23.  *
  24.  *     Kopaonik [subota 01.02.] -15 >> 2
  25.  *
  26.  * Treba napraviti jednu nit koja ce samo citati podatke iz ulaznih datoteka, jednu nit koja ce
  27.  * samo pisati spremljene podatke u izlazne datoteke i 4 niti radnika koji ce na osnovu podataka iz
  28.  * ulaznih datoteka generisati sve neophodno za ispis u izlazne datoteke.
  29. */
  30.  
  31. #include <iostream>
  32. #include <thread>
  33. #include <mutex>
  34. #include <condition_variable>
  35. #include <vector>
  36. #include <algorithm>
  37. #include <fstream>
  38. #include <regex>
  39.  
  40. #define BR_RADNIKA 4
  41. #define BR_MERENJA_TEMPERATURE 13
  42. #define MINIMALNA_IDEALNA_TEMPERATURA -5
  43. #define MAKSIMALNA_IDEALNA_TEMPERATURA 3
  44.  
  45. using namespace std;
  46.  
  47. class StanjeSkijalistaNaDan {
  48. private:
  49.     // TODO dodati polja po potrebi
  50.     string planina;
  51.     string dan;
  52.     string datum;
  53.     vector<int> temperature;
  54.     int minimalna;
  55.     int maksimalna;
  56. public:
  57.     // TODO dodati metode po potrebi
  58.     StanjeSkijalistaNaDan() {}
  59.     StanjeSkijalistaNaDan(string planina, string dan, string datum){
  60.         this->planina = planina;
  61.         this->dan = dan;
  62.         this->datum = datum;
  63.     }
  64.     void setTemperature(vector<int> temperature){
  65.         this->temperature = temperature;
  66.         minimalna  = *min_element(temperature.begin(), temperature.end());
  67.         maksimalna = *max_element(temperature.begin(), temperature.end());
  68.     }
  69.  
  70.     int getMin()const{
  71.         return minimalna;
  72.     }
  73.     int getMax()const{
  74.         return maksimalna;
  75.     }
  76.  
  77.     friend ostream& operator<<(ostream& os, StanjeSkijalistaNaDan s){
  78.         os << s.planina << " [" << s.dan << " " << s.datum << "] " << s.minimalna << " << " << s.maksimalna << endl;
  79.         return os;
  80.     }
  81. private:
  82.     // TODO dodati metode po potrebi
  83. };
  84.  
  85. /** Klasa koja modeluje "postansko sanduce" izmedju citaca i radnika.
  86. */
  87. template<typename T>
  88. class RedoviIzDatoteke {
  89. private:
  90.     mutex podaci_mx;                       // propusnica za sinhronizaciju nad svim poljima klase
  91.     // TODO dodati polja po potrebi
  92.     condition_variable cv;
  93.     bool kraj;
  94.     int workers;
  95.     vector<string> data;
  96. public:
  97.     RedoviIzDatoteke(): kraj(false), workers(0) {}
  98.  
  99.     void dodaj(T redIzDatoteke) {
  100.         // TODO
  101.         unique_lock<mutex> l(podaci_mx);
  102.         data.push_back(redIzDatoteke);
  103.         cv.notify_one();
  104.     }
  105.  
  106.     bool preuzmi(T &redIzDatoteke) {
  107.         // TODO
  108.         unique_lock<mutex> l(podaci_mx);
  109.         while(data.empty() && !kraj){
  110.             cv.wait(l);
  111.         }
  112.         if(jeLiKraj()){
  113.             return false;
  114.         }
  115.         redIzDatoteke = data.back();
  116.         data.pop_back();
  117.         return true;
  118.     }
  119.  
  120.     // TODO dodati metode po potrebi
  121.     void addWorker(){
  122.         unique_lock<mutex> l(podaci_mx);
  123.         ++workers;
  124.     }
  125.     void removeWorker(){
  126.         unique_lock<mutex> l(podaci_mx);
  127.         if((--workers) == 0){
  128.             kraj = true;
  129.             cv.notify_one();
  130.         }
  131.     }
  132. private:
  133.     /**
  134.      * Provera da li treba da cekamo podatke. Vraca istinu samo onda kada u kolekciji
  135.      * nema podataka ali istovremeno i nije objavljen kraj stvaranja podataka.
  136.     */
  137.     bool daLiCekamPodatke() {
  138.         // TODO
  139.         return data.empty() && !kraj;
  140.     }
  141.  
  142.     /**
  143.      * Provera da li smo zavrsili sa citanjem podataka. Vraca istinu samo onda kada nema vise podataka
  144.      * u kolekciji i sve niti stvaraoci podataka su se odjavili.
  145.     */
  146.     bool jeLiKraj() {
  147.         // TODO
  148.         return data.empty() && kraj;
  149.     }
  150. };
  151.  
  152.  
  153. /** Klasa koja modeluje "postansko sanduce" izmedju radnika i pisaca.
  154. */
  155. template<typename T>
  156. class PodaciZaIspis {
  157. private:
  158.     mutex podaci_mx;                       // propusnica za sinhronizaciju nad svim poljima klase
  159.     // TODO dodati polja po potrebi
  160.     condition_variable cv;
  161.     bool kraj;
  162.     int br_stvaralaca_podataka;
  163.     vector<T> data;
  164. public:
  165.     PodaciZaIspis(): kraj(false), br_stvaralaca_podataka(0) {}  // na pocetku nije kraj i nema radnika
  166.  
  167.     void dodaj(T stanjeSkijalista) {
  168.         // TODO
  169.         unique_lock<mutex> l(podaci_mx);
  170.         data.push_back(stanjeSkijalista);
  171.         cv.notify_one();
  172.     }
  173.  
  174.     bool preuzmi(T &stanjeSkijalista) {
  175.         // TODO
  176.         unique_lock<mutex> l(podaci_mx);
  177.         while(daLiCekamPodatke()){
  178.             cv.wait(l);
  179.         }
  180.        
  181.         if(jeLiKraj()){
  182.             return false;
  183.         }
  184.         stanjeSkijalista = data.back();
  185.         data.pop_back();
  186.         return true;
  187.     }
  188.  
  189.     // TODO dodati metode po potrebi
  190.     void addWorker(){
  191.         unique_lock<mutex> l(podaci_mx);
  192.         ++br_stvaralaca_podataka;
  193.     }
  194.     void removeWorker(){
  195.         unique_lock<mutex> l(podaci_mx);
  196.         if((--br_stvaralaca_podataka) == 0){
  197.             kraj = true;
  198.             cv.notify_all();
  199.         }
  200.     }
  201.  
  202. private:
  203.     /**
  204.      * Provera da li treba da cekamo podatke. Vraca istinu samo onda kada u kolekciji
  205.      * nema podataka ali istovremeno i nije objavljen kraj stvaranja podataka.
  206.     */
  207.     bool daLiCekamPodatke() {
  208.         // TODO
  209.         return data.empty() && !kraj;
  210.     }
  211.  
  212.     /**
  213.      * Provera da li smo zavrsili sa citanjem podataka. Vraca istinu samo onda kada nema vise podataka
  214.      * u kolekciji i sve niti stvaraoci podataka su se odjavili.
  215.     */
  216.     bool jeLiKraj() {
  217.         // TODO
  218.         return data.empty() && kraj;
  219.     }
  220. };
  221.  
  222. void citac(vector<string> imena_ulaznih_datoteka, RedoviIzDatoteke<string>& redovi_iz_ulaznih_datoteka) {
  223.     // TODO
  224.     redovi_iz_ulaznih_datoteka.addWorker();
  225.     for(vector<string>::const_iterator i = imena_ulaznih_datoteka.begin(); i != imena_ulaznih_datoteka.end(); ++i){
  226.         ifstream file(*i);
  227.         string line,
  228.                planina = (*i).substr(0, (*i).find(".txt"));
  229.         cout << "Zapocinjem obradjivanje datoteke: " + *i + ":" << endl;
  230.         if(file.is_open()){
  231.             while(getline(file, line)){
  232.                 redovi_iz_ulaznih_datoteka.dodaj("" + planina + " " + line);
  233.             }
  234.         }
  235.         file.close();
  236.     }
  237.     redovi_iz_ulaznih_datoteka.removeWorker();
  238. }
  239.  
  240. void radnik(RedoviIzDatoteke<string>& redovi_iz_ulaznih_datoteka, PodaciZaIspis<StanjeSkijalistaNaDan>& pripremljeni_podaci){
  241.     // TODO
  242.     pripremljeni_podaci.addWorker();
  243.     regex main_r("([A-Za-z]+) ([a-z]+) ([0-9\\.]+) (.+)");
  244.     regex temp_r(" ([0-9\\-]+)");
  245.     string line;
  246.     smatch main_match;
  247.     smatch temp_match;
  248.     vector<int> temperature;
  249.     StanjeSkijalistaNaDan stanje;
  250.     while(redovi_iz_ulaznih_datoteka.preuzmi(line)){
  251.         if(regex_search(line, main_match, main_r)){
  252.             stanje = StanjeSkijalistaNaDan(main_match[1], main_match[2], main_match[3]);
  253.             while(regex_search(line, temp_match, temp_r)){
  254.                 temperature.push_back(stoi(temp_match[1]));
  255.                 line = temp_match.suffix();
  256.             }
  257.             stanje.setTemperature(temperature);
  258.             pripremljeni_podaci.dodaj(stanje);
  259.         }//ako nije u formi necemo je unositi u podatke
  260.     }
  261.     pripremljeni_podaci.removeWorker();
  262. }
  263.  
  264. void pisac(PodaciZaIspis<StanjeSkijalistaNaDan>& pripremljeni_podaci) {
  265.     // TODO
  266.     ofstream file_idealno("idealno.txt"),
  267.              file_lose("lose.txt");
  268.     if(file_idealno.is_open() && file_lose.is_open()){
  269.         StanjeSkijalistaNaDan stanje;
  270.         while(pripremljeni_podaci.preuzmi(stanje)){
  271.             if(stanje.getMin() >= MINIMALNA_IDEALNA_TEMPERATURA && stanje.getMax() <= MAKSIMALNA_IDEALNA_TEMPERATURA){
  272.                 file_idealno << stanje;
  273.             }else{
  274.                 file_lose << stanje;
  275.             }
  276.         }
  277.     }
  278.     file_idealno.close();
  279.     file_lose.close();
  280. }
  281.  
  282.  
  283. int main() {
  284.     RedoviIzDatoteke<string> redovi;
  285.     PodaciZaIspis<StanjeSkijalistaNaDan> podaci;
  286.     vector<string> imena = {"Jahorina.txt","Kopaonik.txt","Zlatibor.txt"};
  287.     thread t_reader(citac, imena, ref(redovi));
  288.     thread t_workers[4];
  289.     thread t_writer(pisac, ref(podaci));
  290.     t_reader.join();
  291.     for(thread &th : t_workers){
  292.         th = thread(radnik, ref(redovi), ref(podaci));
  293.     }
  294.     for(thread &th : t_workers){
  295.         th.join();
  296.     }
  297.     t_writer.join();
  298.     return 0;
  299. }
Advertisement
Add Comment
Please, Sign In to add comment