Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * Napisati C++ program koji iz ulazne datoteke cita podatke o temperaturi u toku vikenda sa ski
- * staza na Kopaoniku, Zlatiboru i Jahorini i odredjuje koji dani i na kojoj planini su idealni
- * za skijanje a koji nisu. Neki idealni opseg temperature za skijanje je od -5 do 3 stepena.
- *
- * Za svaku od planina postoji posebna datoteka cije ime se sastoji od imena planine i prosirenja
- * (ekstenzije) ".txt". U svakoj pojedinacnoj datoteci se u jednom redu nalaze podaci za jedan dan.
- * Jedan red sadrzi redom ime_dana, datum, i potom izmerene temperature. Temperatura se meri na
- * svakih sat vremena, pocevsi od 8 ujutru, do 8 uvece. Svi podaci su odvojeni razmakom.
- *
- * Izgled jednog reda iz ulaznih datoteka "Kopaonik.txt" "Zlatibor.txt" "Jahorina.txt"
- *
- * subota 01.02. -15 -13 -10 -8 -3 0 -2 -3 2 2 -5 -7 -3
- *
- * Treba za svaki dan pronaci najnizu i najvisu dnevnu temperaturu. Ukoliko minimalna i maksimalna
- * temperatura upadaju u navedeni opseg, treba informacije za taj dan ispisati u datoteku
- * "idealno.txt", u suprotnom u datoteku "lose.txt".
- *
- * Ispis u izlaznu datoteku treba da prati format:
- * <ime_planine> [<ime_dana> <datum>] <min. temp.> >> <maks. temp.>
- *
- * Primer ispisa u bilo kojoj od izlaznih datoteka "idealno.txt", "lose.txt":
- *
- * Kopaonik [subota 01.02.] -15 >> 2
- *
- * Treba napraviti jednu nit koja ce samo citati podatke iz ulaznih datoteka, jednu nit koja ce
- * samo pisati spremljene podatke u izlazne datoteke i 4 niti radnika koji ce na osnovu podataka iz
- * ulaznih datoteka generisati sve neophodno za ispis u izlazne datoteke.
- */
- #include <iostream>
- #include <thread>
- #include <mutex>
- #include <condition_variable>
- #include <vector>
- #include <algorithm>
- #include <fstream>
- #include <regex>
- #define BR_RADNIKA 4
- #define BR_MERENJA_TEMPERATURE 13
- #define MINIMALNA_IDEALNA_TEMPERATURA -5
- #define MAKSIMALNA_IDEALNA_TEMPERATURA 3
- using namespace std;
- class StanjeSkijalistaNaDan {
- private:
- // TODO dodati polja po potrebi
- string planina;
- string dan;
- string datum;
- vector<int> temperature;
- int minimalna;
- int maksimalna;
- public:
- // TODO dodati metode po potrebi
- StanjeSkijalistaNaDan() {}
- StanjeSkijalistaNaDan(string planina, string dan, string datum){
- this->planina = planina;
- this->dan = dan;
- this->datum = datum;
- }
- void setTemperature(vector<int> temperature){
- this->temperature = temperature;
- minimalna = *min_element(temperature.begin(), temperature.end());
- maksimalna = *max_element(temperature.begin(), temperature.end());
- }
- int getMin()const{
- return minimalna;
- }
- int getMax()const{
- return maksimalna;
- }
- friend ostream& operator<<(ostream& os, StanjeSkijalistaNaDan s){
- os << s.planina << " [" << s.dan << " " << s.datum << "] " << s.minimalna << " << " << s.maksimalna << endl;
- return os;
- }
- private:
- // TODO dodati metode po potrebi
- };
- /** Klasa koja modeluje "postansko sanduce" izmedju citaca i radnika.
- */
- template<typename T>
- class RedoviIzDatoteke {
- private:
- mutex podaci_mx; // propusnica za sinhronizaciju nad svim poljima klase
- // TODO dodati polja po potrebi
- condition_variable cv;
- bool kraj;
- int workers;
- vector<string> data;
- public:
- RedoviIzDatoteke(): kraj(false), workers(0) {}
- void dodaj(T redIzDatoteke) {
- // TODO
- unique_lock<mutex> l(podaci_mx);
- data.push_back(redIzDatoteke);
- cv.notify_one();
- }
- bool preuzmi(T &redIzDatoteke) {
- // TODO
- unique_lock<mutex> l(podaci_mx);
- while(data.empty() && !kraj){
- cv.wait(l);
- }
- if(jeLiKraj()){
- return false;
- }
- redIzDatoteke = data.back();
- data.pop_back();
- return true;
- }
- // TODO dodati metode po potrebi
- void addWorker(){
- unique_lock<mutex> l(podaci_mx);
- ++workers;
- }
- void removeWorker(){
- unique_lock<mutex> l(podaci_mx);
- if((--workers) == 0){
- kraj = true;
- cv.notify_one();
- }
- }
- private:
- /**
- * Provera da li treba da cekamo podatke. Vraca istinu samo onda kada u kolekciji
- * nema podataka ali istovremeno i nije objavljen kraj stvaranja podataka.
- */
- bool daLiCekamPodatke() {
- // TODO
- return data.empty() && !kraj;
- }
- /**
- * Provera da li smo zavrsili sa citanjem podataka. Vraca istinu samo onda kada nema vise podataka
- * u kolekciji i sve niti stvaraoci podataka su se odjavili.
- */
- bool jeLiKraj() {
- // TODO
- return data.empty() && kraj;
- }
- };
- /** Klasa koja modeluje "postansko sanduce" izmedju radnika i pisaca.
- */
- template<typename T>
- class PodaciZaIspis {
- private:
- mutex podaci_mx; // propusnica za sinhronizaciju nad svim poljima klase
- // TODO dodati polja po potrebi
- condition_variable cv;
- bool kraj;
- int br_stvaralaca_podataka;
- vector<T> data;
- public:
- PodaciZaIspis(): kraj(false), br_stvaralaca_podataka(0) {} // na pocetku nije kraj i nema radnika
- void dodaj(T stanjeSkijalista) {
- // TODO
- unique_lock<mutex> l(podaci_mx);
- data.push_back(stanjeSkijalista);
- cv.notify_one();
- }
- bool preuzmi(T &stanjeSkijalista) {
- // TODO
- unique_lock<mutex> l(podaci_mx);
- while(daLiCekamPodatke()){
- cv.wait(l);
- }
- if(jeLiKraj()){
- return false;
- }
- stanjeSkijalista = data.back();
- data.pop_back();
- return true;
- }
- // TODO dodati metode po potrebi
- void addWorker(){
- unique_lock<mutex> l(podaci_mx);
- ++br_stvaralaca_podataka;
- }
- void removeWorker(){
- unique_lock<mutex> l(podaci_mx);
- if((--br_stvaralaca_podataka) == 0){
- kraj = true;
- cv.notify_all();
- }
- }
- private:
- /**
- * Provera da li treba da cekamo podatke. Vraca istinu samo onda kada u kolekciji
- * nema podataka ali istovremeno i nije objavljen kraj stvaranja podataka.
- */
- bool daLiCekamPodatke() {
- // TODO
- return data.empty() && !kraj;
- }
- /**
- * Provera da li smo zavrsili sa citanjem podataka. Vraca istinu samo onda kada nema vise podataka
- * u kolekciji i sve niti stvaraoci podataka su se odjavili.
- */
- bool jeLiKraj() {
- // TODO
- return data.empty() && kraj;
- }
- };
- void citac(vector<string> imena_ulaznih_datoteka, RedoviIzDatoteke<string>& redovi_iz_ulaznih_datoteka) {
- // TODO
- redovi_iz_ulaznih_datoteka.addWorker();
- for(vector<string>::const_iterator i = imena_ulaznih_datoteka.begin(); i != imena_ulaznih_datoteka.end(); ++i){
- ifstream file(*i);
- string line,
- planina = (*i).substr(0, (*i).find(".txt"));
- cout << "Zapocinjem obradjivanje datoteke: " + *i + ":" << endl;
- if(file.is_open()){
- while(getline(file, line)){
- redovi_iz_ulaznih_datoteka.dodaj("" + planina + " " + line);
- }
- }
- file.close();
- }
- redovi_iz_ulaznih_datoteka.removeWorker();
- }
- void radnik(RedoviIzDatoteke<string>& redovi_iz_ulaznih_datoteka, PodaciZaIspis<StanjeSkijalistaNaDan>& pripremljeni_podaci){
- // TODO
- pripremljeni_podaci.addWorker();
- regex main_r("([A-Za-z]+) ([a-z]+) ([0-9\\.]+) (.+)");
- regex temp_r(" ([0-9\\-]+)");
- string line;
- smatch main_match;
- smatch temp_match;
- vector<int> temperature;
- StanjeSkijalistaNaDan stanje;
- while(redovi_iz_ulaznih_datoteka.preuzmi(line)){
- if(regex_search(line, main_match, main_r)){
- stanje = StanjeSkijalistaNaDan(main_match[1], main_match[2], main_match[3]);
- while(regex_search(line, temp_match, temp_r)){
- temperature.push_back(stoi(temp_match[1]));
- line = temp_match.suffix();
- }
- stanje.setTemperature(temperature);
- pripremljeni_podaci.dodaj(stanje);
- }//ako nije u formi necemo je unositi u podatke
- }
- pripremljeni_podaci.removeWorker();
- }
- void pisac(PodaciZaIspis<StanjeSkijalistaNaDan>& pripremljeni_podaci) {
- // TODO
- ofstream file_idealno("idealno.txt"),
- file_lose("lose.txt");
- if(file_idealno.is_open() && file_lose.is_open()){
- StanjeSkijalistaNaDan stanje;
- while(pripremljeni_podaci.preuzmi(stanje)){
- if(stanje.getMin() >= MINIMALNA_IDEALNA_TEMPERATURA && stanje.getMax() <= MAKSIMALNA_IDEALNA_TEMPERATURA){
- file_idealno << stanje;
- }else{
- file_lose << stanje;
- }
- }
- }
- file_idealno.close();
- file_lose.close();
- }
- int main() {
- RedoviIzDatoteke<string> redovi;
- PodaciZaIspis<StanjeSkijalistaNaDan> podaci;
- vector<string> imena = {"Jahorina.txt","Kopaonik.txt","Zlatibor.txt"};
- thread t_reader(citac, imena, ref(redovi));
- thread t_workers[4];
- thread t_writer(pisac, ref(podaci));
- t_reader.join();
- for(thread &th : t_workers){
- th = thread(radnik, ref(redovi), ref(podaci));
- }
- for(thread &th : t_workers){
- th.join();
- }
- t_writer.join();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment