Иди на текст

Пета вежба

Темплејтске класе

Нерешени задаци

Задатак 0.

На програмском језику C++ направити темплејтску класу Set која моделира скуп са елементима произвољног типа. Приватни атрибути класе су број елемената скупа и динамички низ елемената, а као јавне чланице:

  • подразумевани конструктор који поставља број елемената скупа на 0,
  • конструктор за постављање броја елемената скупа и заузимање неопходног простора у меморији,
  • деструктор,
  • inline методу која враћа број елемената скупа,
  • методу која испитује да ли задати елемент припада скупу,
  • операторску методу * која одређује пресек два скупа.

Имплементирати и пријатељске оператоске методе:

  • >> - за учитавање елемената скупа,
  • << - за упис елемената скупа.

Такође, направити класу Movie која од приватних атрибута има назив филма, пуно име редитеља и трајање филма, а од јавних чланица:

  • подразумевани конструктор који поставља све податке на нулте вредности,
  • деструктор,
  • оператор = који додељује један објекат класе Movie другом,
  • оператор == који пореди два филма.

Дефинисати и пријатељске операторске методе:

  • << - који штампа назив филма, пуно име редитеља и трајање филма,
  • >> - који учитава све арибуте филма.

У главном програму специјализовати темплејт и тестирати све његове методе за податке типа double и за класу Movie.

Програмски ко̑д

#include <fstream>
#include <iostream>
#include <random>

#include "Movie.h"
#include "Set.h"

int main() {
    auto doubleSet1 = new Set<double>(5);
    auto doubleSet2 = new Set<double>(5);
    auto movieSet = new Set<Movie*>(5);

    std::random_device rd;
    std::mt19937 mt(rd());
    std::uniform_real_distribution<double> dist(-100, 100);

    std::ifstream file("filmovi.txt");

    for (int i = 0; i < 5; i++) {
        if (i % 3) {
            double value = 3;
            doubleSet1->Add(value);
            doubleSet2->Add(value);
        } else {
            double value = dist(mt);
            doubleSet1->Add(value);

            value = dist(mt);
            doubleSet1->Add(value);
        }

        auto movie = new Movie();
        file >> movie;
        movieSet->Add(movie);

        std::cout << movie;
    }

    auto presek = *doubleSet1 * *doubleSet2;

    std::cout << presek;

    delete doubleSet1;
    delete movieSet;

    return 0;
}
#ifndef SET_H
#define SET_H

template<class T>
class Set {
private:
    int size;
    int count;
    T *data;

public:
    Set();

    Set(int size);

    ~Set();

    int Size() const {
        return size;
    }

    bool Contains(T &element) const;

    Set<T> *operator*(const Set<T> &set) const;

    template<class U>
    friend std::ostream &operator<<(std::ostream &os, const Set<U> *set);

    template<class U>
    friend std::istream &operator>>(std::istream &is, Set<U> *set);

    bool Add(T &element);
};

template<class T>
Set<T>::Set() {
    size = 0;
}

template<class T>
Set<T>::Set(int size) {
    this->size = size;
    this->count = 0;
    this->data = new T[size];
}

template<class T>
Set<T>::~Set() {
    delete[] data;
}

template<class T>
bool Set<T>::Contains(T &element) const {
    for (int i = 0; i < count; i++) {
        if (data[i] == element) {
            return true;
        }
    }
    return false;
}

template<class T>
Set<T> *Set<T>::operator*(const Set &set) const {
    auto result = new Set(size + set.size);
    int index = 0;
    for (int i = 0; i < size; i++) {
        if (set.Contains(data[i])) {
            result->data[index++] = data[i];
        }
    }
    result->size = index;

    return result;
}

template<class T>
std::ostream &operator<<(std::ostream &os, const Set<T> *set) {
    os << "size: " << set->size << std::endl;
    for (int i = 0; i < set->size; i++) {
        os << set->data[i] << std::endl;
    }
    return os;
}

template<class T>
std::istream &operator>>(std::istream &is, Set<T> *set) {
    for (int i = 0; i < set.size; i++) {
        is >> set->data[i];
    }
    return is;
}

template<class T>
bool Set<T>::Add(T &element) {
    if (Contains(element)) {
        return false;
    }

    if (count == size) {
        return false;
    }

    data[count++] = element;
    return true;
}

#endif
#ifndef MOVIE_H
#define MOVIE_H
#include <iostream>

class Movie {
private:
    char *name;
    char *directorName;
    int duration;

public:
    Movie();

    ~Movie();

    Movie &operator=(Movie const &movie);

    bool operator==(Movie const &movie) const;

    friend std::ostream &operator<<(std::ostream &os, const Movie *movie);

    friend std::istream &operator>>(std::istream &is, Movie *movie);
};

#endif
#include "Movie.h"
#include <cstring>

Movie::Movie() {
    name = nullptr;
    directorName = nullptr;
    duration = 0;
}

Movie::~Movie() {
    delete[] name;
    delete[] directorName;
}

Movie &Movie::operator=(Movie const &movie) {
    if (this != &movie) {
        delete[] name;
        delete[] directorName;
        name = new char[strlen(movie.name) + 1];
        strcpy(name, movie.name);
        directorName = new char[strlen(movie.directorName) + 1];
        strcpy(directorName, movie.directorName);
        duration = movie.duration;
    }
    return *this;
}

bool Movie::operator==(Movie const &movie) const {
    return strcmp(name, movie.name) == 0 &&
           strcmp(directorName, movie.directorName) == 0 &&
           duration == movie.duration;
}

std::ostream &operator<<(std::ostream &os, const Movie *movie) {
    os << "name: " << movie->name << std::endl;
    os << "directorName: " << movie->directorName << std::endl;
    os << "duration: " << movie->duration << std::endl << std::endl;
    return os;
}

std::istream &operator>>(std::istream &is, Movie *movie) {
    char buffer[256];
    is.getline(buffer, 256);

    movie->name = new char[strlen(buffer) + 1];
    strcpy(movie->name, buffer);

    is.getline(buffer, 256);

    movie->directorName = new char[strlen(buffer) + 1];
    strcpy(movie->directorName, buffer);

    is >> movie->duration;
    is.get();

    return is;
}

Тест подаци

Monsters, Inc.
Pete Docter, David Silverman, Lee Unkrich
92
Finding Nemo
Andrew Stanton, Lee Unkrich
100
Passengers
Morten Tyldum
116
Thor: Love and Thunder
Taika Waititi
118
Guardians of the Galaxy Vol. 3
James Gunn
150

Задатак 1.

Задатак 2.

Задатак 3.

Задатак 4.

Задатак 5.

Задатак 6.

Задатак 7.

Направити шаблонску класу Buffer која представља низ елемената произвољног типа, маскималне дужине задате као нетипски параметар шаблона. Класа има следеће методе:

  • getItem(int index) - враћа елемент на позицији index и низу,
  • getFirst() - враћа први елемент листе,
  • getLast() - враћа задњи елемент листе,
  • add - додаје нови елемент у листи.

Имплементирати и класу Student која ће као приватне чланове имати име и презиме студента, број индекса и просечну оцену са до сада положених испита, а као јавне следеће чланице:

  • конструктор без аргумента,
  • конструктор за копирање,
  • операторску методу = која додељује један објекат класе Student другом.

Такође имплементирати и пријатељске операторске методе:

  • >> за учитавање података о студенту,
  • << за штампање података о студенту.

У main функцији креирати објекат класе Buffer који ради са карактерима и објекат класе Buffer који ради са студентима и тестирати све методе класе Buffer за оба објекта.

Програмски ко̑д

#include <iostream>
#include <fstream>

#include "Buffer.h"
#include "Student.h"

int main() {
    auto karakteri = new Buffer<char, 5>();
    auto studenti = new Buffer<Student, 5>();

    std::ifstream file("studenti.txt");

    for (int i = 0; i < 5; i++) {
        auto s = new Student();
        file >> *s;
        studenti->Add(*s);
        karakteri->Add('a' + i);
    }

    file.close();

    std::cout << karakteri->GetFirst() << std::endl;
    std::cout << karakteri->GetLast() << std::endl;
    std::cout << karakteri->GetItem(2) << std::endl;

    std::cout << studenti->GetFirst();
    std::cout << studenti->GetLast();
    std::cout << studenti->GetItem(4);

    delete karakteri;
    delete studenti;

    return 0;
}
#ifndef BUFFER_H
#define BUFFER_H


template<class T, int n>
class Buffer {
private:
    T items[n];
    int count = 0;

public:
    T GetItem(int index);

    T GetFirst();

    T GetLast();

    bool Add(const T &element);
};

template<class T, int n>
T Buffer<T, n>::GetItem(int index) {
    if (index < 0 || index >= count) {
        throw "Index out of bounds";
    }

    return items[index];
}

template<class T, int n>
T Buffer<T, n>::GetFirst() {
    return GetItem(0);
}

template<class T, int n>
T Buffer<T, n>::GetLast() {
    return GetItem(count - 1);
}

template<class T, int n>
bool Buffer<T, n>::Add(const T &element) {
    if (count >= n) {
        return false;
    }

    items[count++] = element;
    return true;
}


#endif
#ifndef STUDENT_H
#define STUDENT_H
#include <iostream>

class Student {
private:
    char *imePrezime;
    int brojIndeksa;
    double prosecnaOcena;

public:
    Student();

    Student(Student &student);

    Student &operator=(const Student &student);

    friend std::ostream &operator<<(std::ostream &os, const Student &student);

    friend std::istream &operator>>(std::istream &is, Student &student);
};

#endif
#include "Student.h"
#include <cstring>

Student::Student() {
    imePrezime = nullptr;
    brojIndeksa = 0;
    prosecnaOcena = 0;
}

Student::Student(Student &student) {
    imePrezime = new char[strlen(student.imePrezime) + 1];
    strcpy(imePrezime, student.imePrezime);
    brojIndeksa = student.brojIndeksa;
    prosecnaOcena = student.prosecnaOcena;
}

Student &Student::operator=(const Student &student) {
    if (this == &student)
        return *this;

    delete[] imePrezime;
    imePrezime = new char[strlen(student.imePrezime) + 1];
    strcpy(imePrezime, student.imePrezime);
    brojIndeksa = student.brojIndeksa;
    prosecnaOcena = student.prosecnaOcena;

    return *this;
}

std::ostream &operator<<(std::ostream &os, const Student &student) {
    os << "Ime i prezime: " << student.imePrezime << std::endl;
    os << "Broj indeksa: " << student.brojIndeksa << std::endl;
    os << "Prosecna ocena: " << student.prosecnaOcena << std::endl << std::endl;

    return os;
}

std::istream &operator>>(std::istream &is, Student &student) {
    char imePrezime[100];
    int brojIndeksa;
    double prosecnaOcena;

    is.getline(imePrezime, 100);
    is >> brojIndeksa;
    is >> prosecnaOcena;
    is.getline(nullptr, 0);

    student.imePrezime = new char[strlen(imePrezime) + 1];
    strcpy(student.imePrezime, imePrezime);
    student.brojIndeksa = brojIndeksa;
    student.prosecnaOcena = prosecnaOcena;

    return is;
}

Тест подаци

Zarko Matic
19217 10.00
Milica Milic
20000 6.12
Niko Bitan
19200 7.75
Pavle Pavlic
20010 8.30
Test 123
10 9.33

Задатак 8.

Задатак 9.