Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * Napisati C++ program koji cita podatke o studentima iz ulazne datoteke i potom
- * za svakog studenta racuna prosek
- *
- * U ulaznoj datoteci "studenti.csv" se u svakom redu nalaze informacije o studentu:
- * Ime,Prezime,Broj indeksa,Ocene
- * Pritom su ocene odvojene medjusobno zarezima.
- *
- * Prilikom obrade podataka o studentima, mora se proveriti format indeksa da li je validan. Ako nije, zanemariti taj unos.
- * Format indeksa je:
- * [[:alpha:]][[:alnum:]]{1,2}\s[[:digit:]]{1,3}\/[[:digit:]]{4}
- *
- * U tri izlazne datoteke rasporediti studente u zavisnosti od proseka.
- * Ukoliko je prosek > 9.00 potrebno je upisati studenta u datoteku "kandidati_stipendija.csv".
- * Ukoliko je prosek > 8.00 i prosek <= 9.00 potrebno je upisati studenta u datoteku "kandidati_kredit.csv".
- * U ostalim slucajevima upisati studenta u datoteku "ostali.csv".
- * Format u izlaznoj datoteci treba da odgovara sledecem: Ime,Prezime,Broj_indeksa,prosek
- *
- * Treba napraviti jednu nit koja ce samo citati redove ulazne podatke, jednu nit
- * koja ce samo pisati gotove podatke u izlazne datoteke i 10 niti radnika koji ce na osnovu redova
- * iz ulazne datoteke generisati sve neophodno za ispis u izlaznu datoteku.
- */
- #include <iostream>
- #include <mutex>
- #include <condition_variable>
- #include <thread>
- #include <vector>
- #include <fstream>
- #include <regex>
- #include <numeric>
- using namespace std;
- class Student {
- private:
- string ime;
- string prezime;
- string index;
- vector<int> ocene;
- double prosek;
- public:
- Student(){}
- Student(string ime, string prezime, string index){
- this->ime = ime;
- this->prezime = prezime;
- this->index = index;
- }
- void setOcene(vector<int> ocene){
- this->ocene = ocene;
- prosek = accumulate(ocene.begin(),ocene.end(), 0.) / ocene.size();
- }
- double getProsek()const{
- return prosek;
- }
- friend ostream& operator<<(ostream& os, Student s){
- os << s.ime << "," << s.prezime << "," << s.index << "," << s.prosek;
- return os;
- }
- };
- template<typename T>
- class InputData {
- private:
- mutex data_mtx;
- // TODO dodati polja po potrebi
- bool end;
- vector<T> data;
- condition_variable cv;
- int workers;
- public:
- InputData(): end(false), workers(0) {
- // TODO
- }
- void add_data(T data_element) {
- // TODO
- unique_lock<mutex> l(data_mtx);
- data.push_back(data_element);
- cv.notify_one();
- }
- bool remove_data(T &data_element) {
- // TODO
- unique_lock<mutex> l(data_mtx);
- while(data.empty() && !end){
- cv.wait(l);
- }
- if(the_end()){
- return false;
- }
- data_element = data.back();
- data.pop_back();
- return true;
- }
- // TODO dodati metode po potrebi
- void addWorker(){
- unique_lock<mutex> l(data_mtx);
- ++workers;
- }
- void removeWorkers(){
- unique_lock<mutex> l(data_mtx);
- if((--workers) == 0){
- end = true;
- cv.notify_all();
- }
- }
- bool the_end(){
- return data.empty() && end;
- }
- };
- template<typename T>
- class OutputData {
- private:
- mutex data_mtx;
- // TODO dodati polja po potrebi
- condition_variable cv;
- int data_producers_num;
- vector<T> data;
- bool end;
- public:
- OutputData(): end(false), data_producers_num(0) {}
- void add_data(T data_element) {
- unique_lock<mutex> l(data_mtx);
- data.push_back(data_element);
- cv.notify_one();
- }
- bool remove_data(T &data_element) {
- unique_lock<mutex> l(data_mtx);
- while(data.empty() && !end){
- cv.wait(l);
- }
- if(the_end()){
- return false;
- }
- data_element = data.back();
- data.pop_back();
- return true;
- }
- bool the_end() {
- return data.empty() && end;
- }
- // TODO dodati metode po potrebi
- void addWorker(){
- unique_lock<mutex> l(data_mtx);
- ++data_producers_num;
- }
- void removeWorker(){
- unique_lock<mutex> l(data_mtx);
- if((--data_producers_num) == 0){
- end = true;
- cv.notify_all();
- }
- }
- };
- void reader(string input_file_name, InputData<string>& raw_data) {
- // TODO
- raw_data.addWorker();
- ifstream i_file(input_file_name);
- string line;
- while(getline(i_file, line)){
- raw_data.add_data(line);
- }
- i_file.close();
- raw_data.removeWorkers();
- }
- void proccessing_data(InputData<string>& raw_data, OutputData<Student>& proccessed_data){
- // TODO
- proccessed_data.addWorker();
- regex main_r("([A-Za-z]+),([A-Za-z]+),([A-Z 0-9/]+),(.+)");
- regex ocene_r(",([015-9]+)");
- smatch main_match;
- smatch ocene_match;
- Student student;
- string data_line;
- vector<int> ocene;
- while(raw_data.remove_data(data_line)){
- if(regex_search(data_line, main_match, main_r)){
- student = Student(main_match[1], main_match[2], main_match[3]);
- while(regex_search(data_line, ocene_match, ocene_r)){
- ocene.push_back(stoi(ocene_match[1]));
- data_line = ocene_match.suffix();
- }
- student.setOcene(ocene);
- proccessed_data.add_data(student);
- ocene.clear();
- ocene.resize(0);
- } //ovde necemo nista dalje jer ako linija nije u regex formi PRESKACEMO
- }
- proccessed_data.removeWorker();
- }
- void writer(OutputData<Student>& proccessed_data) {
- // TODO
- ofstream file_stipendije("stipendije.csv"),
- file_krediti("krediti.csv"),
- file_ostalo("ostalo.csv");
- Student student;
- bool first_stipendije = true,
- first_krediti = true,
- first_ostalo = true;
- if(file_stipendije.is_open() && file_krediti.is_open() && file_ostalo.is_open()){
- while(proccessed_data.remove_data(student)){
- double prosek = student.getProsek();
- if(prosek > 9.0){
- if(first_stipendije){
- file_stipendije << student;
- first_stipendije = false;
- }else{
- file_stipendije << endl << student;
- }
- }else if(prosek > 8.0 && prosek <= 9.0){
- if(first_krediti){
- file_krediti << student;
- first_krediti = false;
- }else{
- file_krediti << endl << student;
- }
- }else{
- if(first_ostalo){
- file_ostalo << student;
- first_ostalo = false;
- }else{
- file_ostalo << endl << student;
- }
- }
- }
- }
- file_stipendije.close();
- file_krediti.close();
- file_ostalo.close();
- }
- int main() {
- InputData<string> raw_data;
- OutputData<Student> proccessed_data;
- thread th_reader(reader, "studenti.csv", ref(raw_data));
- thread th_writer(writer, ref(proccessed_data));
- thread th_workers[10];
- for(auto &th: th_workers){
- th = thread(proccessing_data, ref(raw_data), ref(proccessed_data));
- }
- th_reader.join();
- for(auto &th: th_workers) {
- th.join();
- }
- th_writer.join();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment