Иди на текст

Трећа вежба

Наслеђивање

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

Задатак 0.

На програмском језику C++ имплементирати класу Funkcija (\(f(x) = kx + n\)). Класа садржи три заштићена атрибута: коефицијенте k и n (представљени реалним бројевима) и назив функције (знаковни низ запамћен у динамичкој зони меморије). Такође, поседује и следеће јавне чланице:

  • подразумевани конструктор који иницијализује коефицијенте k на 1, n на 0, а назив на „Linearna funkcija”,
  • конструктор којим се постављају вредности k и n,
  • виртуалну методу која одређује вредност функције за x,
  • виртуалну методу prikaziFunkciju за штампање атрибута класе,
  • виртуални деструктор који брише податке из динамичке зоне меморије уколико постоје.

Из класе Funkcija извести класе KvadratnaFunkcija, облика \(f(x) = (x + n)^k\), и EksponencijalnaFunkcija, облика \(f(x) = k^{x + n}\) где је \(k = e\). Обе класе треба да имплементују следеће јавне чланице:

  • подразумевани конструктор,
  • конструктор којим се постављају вредности свих атрибута,
  • предефинисану методу која одређује вредност функције за x,
  • предефинисану методу prikaziFunkciju која штампа податке о класи,
  • деструктор који брише податке из динамичке зоне меморије уколико постоје.

У функцији main направити низ од 2019 показивача на објекте класе Funkcija. Поставити низ тако да садржи објекте све три класе по 673 пута. Приказати податке из низа на стандардни излаз. За произвољно унету вредност x приказати податке о функцији која има минималну вредност.

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

#include <random>

#include "EksponencijalnaFunkcija.h"
#include "Funkcija.h"
#include "KvadratnaFunkcija.h"

int main() {
    auto funkcije = new Funkcija*[2019];

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

    int i = 0;
    for (int j = 0; j < 673; j++) {
        funkcije[i++] = new Funkcija(dist(mt), dist(mt));
        funkcije[i++] = new KvadratnaFunkcija(dist(mt), dist(mt));
        funkcije[i++] = new EksponencijalnaFunkcija(dist(mt), dist(mt));
    }

    i = 0;
    for (int j = 1; j < 2019; j++) {
        if (funkcije[j]->Calculate(12) < funkcije[i]->Calculate(12)) {
            i = j;
        }
    }

    funkcije[i]->PrikaziFunkciju();

    delete[] funkcije;

    return 0;
}
#ifndef FUNKCIJA_H
#define FUNKCIJA_H


class Funkcija {
protected:
    double k, n;
    char* naziv;

public:
    Funkcija();

    Funkcija(double k, double n);

    virtual double Calculate(double x);

    virtual ~Funkcija();

    virtual void PrikaziFunkciju();
};


#endif
#include "Funkcija.h"

#include <iostream>

Funkcija::Funkcija() {
    k = 1;
    n = 0;
    naziv = new char[]{"Linearna funkcija"};
}

Funkcija::Funkcija(double k, double n) {
    this->k = k;
    this->n = n;
    naziv = new char[]{"Linearna funkcija"};
}

double Funkcija::Calculate(double x) {
    return k * x + n;
}

Funkcija::~Funkcija() {
    delete[] naziv;
}

void Funkcija::PrikaziFunkciju() {
    std::cout << naziv << ": " << k << "x + " << n << std::endl;
}
#ifndef KVADRATNAFUNKCIJA_H
#define KVADRATNAFUNKCIJA_H
#include "Funkcija.h"


class KvadratnaFunkcija : public Funkcija {
public:
    KvadratnaFunkcija();

    KvadratnaFunkcija(double k, double n);

    double Calculate(double x) override;

    void PrikaziFunkciju() override;

    ~KvadratnaFunkcija() override;
};


#endif
#include "KvadratnaFunkcija.h"

#include <cmath>
#include <iostream>

KvadratnaFunkcija::KvadratnaFunkcija() {
    naziv = new char[]{"Kvadratna funkcija"};
}

KvadratnaFunkcija::KvadratnaFunkcija(double k, double n) : Funkcija(k, n) {
    naziv = new char[]{"Kvadratna funkcija"};
}

double KvadratnaFunkcija::Calculate(double x) {
    return std::pow(x + n, k);
}

void KvadratnaFunkcija::PrikaziFunkciju() {
    std::cout << naziv << ": (x + " << n << ")^" << k << std::endl;
}

KvadratnaFunkcija::~KvadratnaFunkcija() {
    delete[] naziv;
}
#ifndef EKSPONENCIJALNAFUNKCIJA_H
#define EKSPONENCIJALNAFUNKCIJA_H
#include "Funkcija.h"


class EksponencijalnaFunkcija : public Funkcija {
public:
    EksponencijalnaFunkcija();

    EksponencijalnaFunkcija(double k, double n);

    double Calculate(double x) override;

    void PrikaziFunkciju() override;

    ~EksponencijalnaFunkcija() override;
};


#endif
#include "EksponencijalnaFunkcija.h"

#include <cmath>
#include <iostream>

EksponencijalnaFunkcija::EksponencijalnaFunkcija() {
    naziv = new char[]{"Eksponencijalna funkcija"};
}

EksponencijalnaFunkcija::EksponencijalnaFunkcija(double k, double n) : Funkcija(k, n) {
    naziv = new char[]{"Eksponencijalna funkcija"};
}

double EksponencijalnaFunkcija::Calculate(double x) {
    return std::pow(k, x + n);
}

void EksponencijalnaFunkcija::PrikaziFunkciju() {
    std::cout << naziv << ": " << k << "^(x + " << n << ")" << std::endl;
}

EksponencijalnaFunkcija::~EksponencijalnaFunkcija() {
    delete[] naziv;
}

Задатак 1.

На програмском језику C++ имплементирати класу Figura. Класа садржи два заштићена атрибута: број страница и низ страница (низ реалних бројева запамћених у динамичкој зони меморије). Такође, поседује и следеће јавне чланице:

  • подразумевани конструктор који иницијализује број страница на 0,
  • конструктор којим се постављају странице као и њихов број,
  • виртуалну методу која рачуна површину,
  • виртуалну методу Prikazi за штампање атрибута класе,
  • виртуални деструктор који брише податке из динамичке зоне меморије уколико постоје.

Из класе Figura извести класе Kvadrat и Pravougaonik. Обе класе треба да имплементују следеће чланице:

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

За класу Kvadrat додати конструктор којим се све странице постављају на вредност a. За класу Pravougaonik додати конструктор којим се све странице постављају одговарајућим вредностима a и b.

У функцији main инстанцирати низ од 2018 показивача на објекте класе Figura. Поставити низ тако да садржи по најмање 1009 објеката класе Kvadrat и Pravougaonik. Приказати податке из низа на стандардни излаз. Сортирати низ по површини, а затим сачувати низ у текстуалну датотеку.

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

#include <fstream>
#include <random>

#include "Figura.h"
#include "Kvadrat.h"
#include "Pravougaonik.h"

int main() {
    auto figure = new Figura*[2018];

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

    int i = 0;
    for (int j = 0; j < 1009; j++) {
        figure[i++] = new Kvadrat(dist(mt));
        figure[i++] = new Pravougaonik(dist(mt), dist(mt));
    }

    for (int j = 0; j < 2018; j++) {
        figure[j]->Prikazi();
    }

    for (int j = 0; j < 2017; j++) {
        for (int k = j + 1; k < 2018; k++) {
            if (figure[j]->Povrsina() > figure[k]->Povrsina()) {
                auto tmp = figure[j];
                figure[j] = figure[k];
                figure[k] = tmp;
            }
        }
    }

    std::ofstream out("figure.txt");
    for (int j = 0; j < 2018; j++) {
        out << figure[j]->Povrsina() << std::endl;
    }

    out.close();

    delete[] figure;

    return 0;
}
#ifndef FIGURA_H
#define FIGURA_H


class Figura {
protected:
    int brStranica;
    double *stranice;

public:
    Figura();

    Figura(int brStranica, double *stranice);

    virtual double Povrsina();

    virtual void Prikazi();

    virtual ~Figura();
};


#endif
#include "Figura.h"

#include <iostream>

Figura::Figura() {
    brStranica = 0;
    stranice = nullptr;
}

Figura::Figura(int brStranica, double *stranice) {
    this->brStranica = brStranica;
    this->stranice = stranice;
}

double Figura::Povrsina() {
    return 0;
}

void Figura::Prikazi() {
    std::cout << "[" << brStranica << "]: ";
    for (int i = 0; i < brStranica; i++) {
        std::cout << stranice[i] << " ";
    }
    std::cout << std::endl;
}

Figura::~Figura() {
    delete[] stranice;
}
#ifndef KVADRAT_H
#define KVADRAT_H
#include "Figura.h"


class Kvadrat : public Figura {
public:
    Kvadrat();

    Kvadrat(double a);

    double Povrsina() override;

    void Prikazi() override;

    ~Kvadrat() override;
};


#endif
#include "Kvadrat.h"

#include <iostream>

Kvadrat::Kvadrat() : Figura(4, new double[4]) {

}

Kvadrat::Kvadrat(double a) : Figura(4, new double[4]) {
    stranice[0] = stranice[1] = stranice[2] = stranice[3] = a;
}

double Kvadrat::Povrsina() {
    return stranice[0] * stranice[0];
}

void Kvadrat::Prikazi() {
    std::cout << "Kvadrat: a = " << stranice[0] << std::endl;
}

Kvadrat::~Kvadrat() {
    delete[] stranice;
}
#ifndef PRAVOUGAONIK_H
#define PRAVOUGAONIK_H
#include "Figura.h"


class Pravougaonik : public Figura {
public:
    Pravougaonik();

    Pravougaonik(double a, double b);

    double Povrsina() override;

    void Prikazi() override;

    ~Pravougaonik() override;
};


#endif
#include "Pravougaonik.h"

#include <iostream>

Pravougaonik::Pravougaonik() : Figura(4, new double[4]) {

}

Pravougaonik::Pravougaonik(double a, double b) : Figura(4, new double[4]) {
    stranice[0] = stranice[2] = a;
    stranice[1] = stranice[3] = b;
}

double Pravougaonik::Povrsina() {
    return stranice[0] * stranice[1];
}

void Pravougaonik::Prikazi() {
    std::cout << "Pravougaonik: a = " << stranice[0] << ", b = " << stranice[1] << std::endl;
}

Pravougaonik::~Pravougaonik() {
    delete[] stranice;
}

Задатак 2.

На програмском језику C++ имплементовати класу Point. Класа садржи два заштићена атрибута: координате x и y (представљене реалним бројевима) и следеће јавне чланице:

  • подразумевани конструктор који иницијализује вредност координата на 0,
  • конструктор којим се постављају вредност x и y координата,
  • методу за одређивање растојања између две тачке,
  • виртуалу методу printData за штампање атрибута класе,
  • виртуални деструктор.

Из класе Point јавно извести класу PointCity која означава локацију града на географској карти. Ова класа саджи приватне атрибуте: назив града (знаковни низ запамћен у динамичкој зони меморије), назив државе којој припада (знаковни низ запамћен у динамичкој зони меморије) и број становника, као и следеће јавне чланице:

  • подразумевани конструктор,
  • конструктор којим се постављају вредности свих атрибута,
  • предефинисану методу printData која штампа податке о класи (додати назив и број становника),
  • деструктор који брише податке из динамичке зоне меморије уколико постоје.

У функцији main инстанцирати низ објеката класе PointCity на основу података из унапред спремљене датотеке (LV3Zad3.txt). Подаци су уписани у формату назив града, па назив државе којој припада па број становника. Подаци су међусобно одвојени табулатом, а називи градова и држава могу да имају бланко знак у себи, па је потребно да се и томе води рачуна.

Пример тест података

Belgrade  Serbia 1,166,763[210]

Los Angeles  United States 3,884,307[103]

Обратити пажњу да број становника није приказан као стандардни цео број, већ има и симболе груписања цифара које би требало да се избаце. Такође, након броја становника (у већини случајева) стоји и референца на извор које треба да се уклоне пре конвертовања текстуалне у бројну вредност. У датом примеру 1,166,763[210] треба да се евалуира као 1166763.

Листу градова сортирати по броју становника и сортирану листу уписати у датотеку на исти начин као што је листа из почетне датотеке (подаци о једном граду смештени у оквиру једног реда, најпре назив града, па државе и на крају број становника).

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

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

#include "PointCity.h"

int main() {
    std::ifstream file("LV3Zad3.txt");

    if (!file.is_open()) {
        std::cout << "File not found!" << std::endl;
        return 1;
    }

    int count = 0;
    std::string line;


    while (std::getline(file, line)) {
        if (!line.empty())
            count++;
    }

    file.clear();
    file.seekg(0, std::ios::beg);

    auto cities = new PointCity*[count];

    std::random_device rd;
    std::mt19937 mt(rd());
    std::uniform_int_distribution<int> dist(-100, 100);

    int i = 0;
    while (std::getline(file, line)) {
        if (line.empty()) {
            continue;
        }

        std::istringstream iss(line);
        std::string country, city, population;

        std::getline(iss, city, '\t');
        std::getline(iss, country, '\t');
        std::getline(iss, population, '\t');

        int popNum = 0;

        for (int j = 0; j < population.length(); j++) {
            if (population[j] == '[') {
                break;
            }

            if (std::isdigit(population[j])) {
                popNum *= 10;
                popNum += population[j] - '0';
                std::cout << population[j];
            }
        }

        cities[i++] = new PointCity(city.data(), country.data(), popNum, dist(mt), dist(mt));
    }

    file.close();

    for (int j = 0; j < count - 1; j++) {
        for (int k = j + 1; k < count; k++) {
            if (cities[j]->Population() < cities[k]->Population()) {
                auto temp = cities[j];
                cities[j] = cities[k];
                cities[k] = temp;
            }
        }
    }

    std::ofstream outFile("LV3Zad3Out.txt");

    for (int j = 0; j < count; j++) {
        outFile << *cities[j];
    }

    out.close();

    delete[] cities;

    return 0;
}
#ifndef POINT_H
#define POINT_H


class Point {
protected:
    double x;
    double y;

public:
    Point();

    Point(double x, double y);

    double Distance(Point p);

    virtual void PrintData();

    virtual ~Point();
};


#endif
#include "Point.h"

#include <cmath>
#include <iostream>

Point::Point() {
    this->x = 0;
    this->y = 0;
}

Point::Point(double x, double y) {
    this->x = x;
    this->y = y;
}

double Point::Distance(Point p) {
    return sqrt(pow(this->x - p.x, 2) + pow(this->y - p.y, 2));
}

void Point::PrintData() {
    std::cout << "(" << x << ", " << y << ") ";
}

Point::~Point() = default;
#ifndef POINTCITY_H
#define POINTCITY_H
#include <iosfwd>
#include <bits/char_traits.h>

#include "Point.h"


class PointCity : public Point {
private:
    char *cityName;
    char *countryName;
    int population;

public:
    PointCity();

    PointCity(char *cityName, char *countryName, int population, double x, double y);

    void PrintData() override;

    int Population();

    friend std::ostream &operator<<(std::ostream &os, const PointCity &pc);

    ~PointCity() override;
};


#endif
#include "PointCity.h"

#include <cstring>
#include <iostream>

PointCity::PointCity() {
    this->cityName = nullptr;
    this->countryName = nullptr;
    this->population = 0;
}

PointCity::PointCity(char *cityName, char *countryName, int population, double x, double y) : Point(x, y) {
    this->cityName = new char[strlen(cityName) + 1];
    this->countryName = new char[strlen(countryName) + 1];
    strcpy(this->cityName, cityName);
    strcpy(this->countryName, countryName);
    this->population = population;
}

void PointCity::PrintData() {
    std::cout << "(" << x << ", " << y << ")\t" << cityName << "\t" << countryName << "\t" << population << "\t" << std::endl;
}

int PointCity::Population() {
    return population;
}

std::ostream &operator<<(std::ostream &os, const PointCity &pc) {
    os << pc.cityName << "\t" << pc.countryName << "\t" << pc.population << std::endl;
    return os;
}

PointCity::~PointCity() {
    delete[] this->cityName;
    delete[] this->countryName;
}

Задатак 3.

На програмском језику C++ направити класу Buffer која као приватне чланове садржи:

  • капацитет бафера,
  • број уписаних елемената у бафер,
  • динамички низ елемената типа int који представља сам бафер.

Класа садржи и јавне чанове:

  • конструктор који иницијализује капацитет бафера,
  • деструктор,
  • виртуелну методу push за додавање новог елемента на крају бафера,
  • виртуелну методу pop за избацивање елемента са почетка бафера,
  • виртуелну методу Clear која избацује све елементе из бафера.

Из класе Buffer извести класе QueueBuffer и OrderedBuffer.

Функционалност за QueueBuffer треба да буду следеће:

  • метода push треба да дода елемент на прво слободно место у бафер,
  • метода Clear функционише исто као и из основне класе,
  • метода pop треба да избацује претпоследњи елемент из бафера. Ако бафер има само један елемент, онда треба да избаци њега.

Функционалност за OrderedBuffer треба да буду следеће:

  • метода Clear треба да вредност свих елемената постави на 0,
  • метода push треба да дода нови елемент у бафер тако да садржај бафера остане сортиран у растућем редоследу,
  • метода pop треба да избаци елемент из средине бафера.

У функцији main декларисати три показивача на класу Buffer, а затим динамички направити објекте класе Buffer, QueueBuffer и OrderedBuffer и испробати све методе чланице, тако што кроз 2018 пута се понови следећа секвенца за сваки од објеката:

  • три пута позвати push са случајно генерисаним целим бројем,
  • два пута позвати pop,
  • у сваком педесетом циклусу позвати Clear,
  • након сваког стотог циклуса штампати садржај бафера.

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

#include <iostream>
#include <random>

#include "Buffer.h"
#include "QueueBuffer.h"
#include "OrderedBuffer.h"

int main() {
    Buffer *buf1, *buf2, *buf3;

    buf1 = new Buffer(10);
    buf2 = new QueueBuffer(10);
    buf3 = new OrderedBuffer(10);

    std::random_device rd;
    std::mt19937 mt(rd());
    std::uniform_int_distribution<int> dist(-100, 100);

    for (int i = 1; i <= 2018; i++) {
        for (int j = 0; j < 3; j++) {
            buf1->Push(dist(mt));
            buf2->Push(dist(mt));
            buf3->Push(dist(mt));
        }

        for (int j = 0; j < 2; j++) {
            buf1->Pop();
            buf2->Pop();
            buf3->Pop();
        }

        if (i % 50 == 0) {
            buf1->Clear();
            buf2->Clear();
            buf3->Clear();
        }

        if (i % 100 == 0) {
            buf1->Print();
            buf2->Print();
            buf3->Print();
            std::cout << std::endl;
        }
    }

    delete buf1;
    delete buf2;
    delete buf3;

    return 0;
}
#ifndef BUFFER_H
#define BUFFER_H


class Buffer {
protected:
    int size;
    int count;
    int *data;

public:
    Buffer(int size);

    ~Buffer();

    virtual bool Push(int value);

    virtual int Pop();

    virtual void Clear();

    void Print();
};


#endif
#include "Buffer.h"

#include <iostream>

Buffer::Buffer(int size) {
    this->size = size;
    this->count = 0;
    this->data = new int[size];
}

Buffer::~Buffer() {
    delete[] this->data;
}

bool Buffer::Push(int value) {
    if (this->count == this->size) {
        return false;
    }

    this->data[this->count++] = value;

    return true;
}

int Buffer::Pop() {
    if (this->count == 0) {
        return 0;
    }

    int value = this->data[0];
    this->count--;

    for (int i = 0; i < this->count; i++) {
        this->data[i] = this->data[i + 1];
    }

    return value;
}

void Buffer::Clear() {
    this->count = 0;
}

void Buffer::Print() {
    for (int i = 0; i < this->count; i++) {
        std::cout << this->data[i] << " ";
    }

    std::cout << std::endl;
}
#ifndef QUEUEBUFFER_H
#define QUEUEBUFFER_H
#include "Buffer.h"


class QueueBuffer : public Buffer {
public:
    QueueBuffer(int size);

    bool Push(int value) override;

    int Pop() override;

    void Clear() override;
};


#endif
#include "QueueBuffer.h"

QueueBuffer::QueueBuffer(int size) : Buffer(size) {}

bool QueueBuffer::Push(int value) {
    if (this->count == this->size) {
        return false;
    }

    this->data[this->count++] = value;

    return true;
}

int QueueBuffer::Pop() {
    if (this->count == 0) {
        return 0;
    }

    if (this->count == 1) {
        return this->data[--this->count];
    }

    int value = this->data[this->count - 2];
    this->data[this->count - 2] = this->data[this->count - 1];
    this->count--;

    return value;
}

void QueueBuffer::Clear() {
    this->count = 0;
}
#ifndef ORDEREDBUFFER_H
#define ORDEREDBUFFER_H
#include "Buffer.h"


class OrderedBuffer : public Buffer {
public:
    OrderedBuffer(int size);

    bool Push(int value) override;

    int Pop() override;

    void Clear() override;
};


#endif
#include "OrderedBuffer.h"

OrderedBuffer::OrderedBuffer(int size) : Buffer(size) {}

bool OrderedBuffer::Push(int value) {
    if (this->count == this->size) {
        return false;
    }

    int i = 0;
    while (i < this->count && this->data[i] < value) {
        i++;
    }

    for (int j = this->count; j > i; j--) {
        this->data[j] = this->data[j - 1];
    }

    this->data[i] = value;
    this->count++;

    return true;
}

int OrderedBuffer::Pop() {
    if (this->count == 0) {
        return 0;
    }

    int value = this->data[this->count / 2];
    for (int i = this->count / 2; i < this->count - 1; i++) {
        this->data[i] = this->data[i + 1];
    }

    this->count--;

    return value;
}

void OrderedBuffer::Clear() {
    for (int i = 0; i < this->count; i++) {
        this->data[i] = 0;
    }

    this->count = 0;
}

Задатак 4.

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

  • title - назив команде,
  • value - вредност параметра (char*),
  • конструктор који поставља параметре title и value,
  • виртуалну методу execute (извршење команде) која исписује назив команде (title).

Из класе Command извести три класе: Draw, Save и Print. Свака класа дефинише title („Draw”, „Save”, „Print”) и предефинише execute методу (исписује параметре title и value извршене операције).

Направити класу CommandHistory која памти команде и има реализован undo механизам тако што класа садржи следеће чланове:

  • вектор показивача на објекте класе Command величине 2019,
  • тренутни број запамћених команди,
  • методу undo() која брише задњи елемент листе,
  • методу create(int x) која на основу параметра x прави одговарајућу команду (објекат класе Draw, Save, Print - уколико у вектору команди нема више места брише се прва уписана команда и додаје нова),
  • методу execute() која позива методу execute() задње издате команде.

У функцији main инстанцирати објекат класе CommandHistory и испробати све методе свих направљених класа. Напунити CommandHistory са по 673 Draw, Save и Print команди, извршити их и испразнити бафер.

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

#include "CommandHistory.h"
#include "Draw.h"
#include "Save.h"
#include "Print.h"

int main() {
    auto cmd0 = new Command(new char[]{"Test command"}, new char[]{"This is a test"});
    auto cmd1 = new Draw(new char[]{"Command to Draw"});
    auto cmd2 = new Save(new char[]{"Command to Save"});
    auto cmd3 = new Print(new char[]{"Command to Print"});

    cmd0->Execute();
    cmd1->Execute();
    cmd2->Execute();
    cmd3->Execute();

    delete cmd0;
    delete cmd1;
    delete cmd2;
    delete cmd3;

    auto history = new CommandHistory();

    for (int j = 0; j < 673; j++) {
        history->Create(j % 3);
    }

    for (int i = 0; i < 2019; i++) {
        history->Execute();
        history->Undo();
    }

    delete history;

    return 0;
}
#ifndef COMMAND_H
#define COMMAND_H


class Command {
protected:
    char *title;
    char *value;

public:
    Command(char *title, char *value);

    virtual void Execute();
};


#endif
#include "Command.h"

#include <cstring>
#include <iostream>

Command::Command(char* title, char* value) {
    this->title = new char[strlen(title) + 1];
    strcpy(this->title, title);
    this->value = new char[strlen(value) + 1];
    strcpy(this->value, value);
}

void Command::Execute() {
    std::cout << this->title << std::endl;
}
#ifndef DRAW_H
#define DRAW_H
#include "Command.h"


class Draw : public Command {
public:
    Draw(char *value);

    void Execute() override;
};


#endif
1
2
3
4
5
6
7
8
9
#include "Draw.h"

#include <iostream>

Draw::Draw(char *value) : Command(new char[]{"Draw"}, value) {}

void Draw::Execute() {
    std::cout << this->title << ": " << this->value << std::endl;
}
#ifndef SAVE_H
#define SAVE_H
#include "Command.h"


class Save : public Command {
public:
    Save(char *value);

    void Execute() override;
};


#endif
1
2
3
4
5
6
7
8
9
#include "Save.h"

#include <iostream>

Save::Save(char *value) : Command(new char[]{"Save"}, value) {}

void Save::Execute() {
    std::cout << this->title << ": " << this->value << std::endl;
}
#ifndef PRINT_H
#define PRINT_H
#include "Command.h"


class Print : public Command {
public:
    Print(char *value);

    void Execute() override;
};


#endif
1
2
3
4
5
6
7
8
9
#include "Print.h"

#include <iostream>

Print::Print(char *value) : Command(new char[]{"Print"}, value) {}

void Print::Execute() {
    std::cout << this->title << ": " << this->value << std::endl;
}
#ifndef COMMANDHISTORY_H
#define COMMANDHISTORY_H
#include "Command.h"


class CommandHistory {
private:
    Command **commands = new Command*[2019];
    int count= 0;

public:
    bool Undo();

    bool Create(int x);

    bool Execute();

    ~CommandHistory();
};


#endif
#include "CommandHistory.h"

#include <cstdlib>

#include "Command.h"
#include "Draw.h"
#include "Save.h"
#include "Print.h"

enum COMMAND {
    DRAW,
    SAVE,
    PRINT,
};

char *randStr(int len) {
    char *str = new char[len + 1];
    for (int i = 0; i < len; i++) {
        str[i] = rand() % 26 + 97;
    }
    str[len] = '\0';
    return str;

}

bool CommandHistory::Create(int x) {
    Command *cmd;
    char *val = randStr(10);

    switch (x) {
        case DRAW:
            cmd = new Draw(val);
            break;
        case SAVE:
            cmd = new Save(val);
            break;
        case PRINT:
            cmd = new Print(val);
            break;
        default:
            return false;
    }

    delete val;

    commands[count++] = cmd;

    return true;
}

bool CommandHistory::Undo() {
    if (count == 0) {
        return false;
    }

    delete commands[count - 1];
    commands[count - 1] = nullptr;

    count--;

    return true;
}

bool CommandHistory::Execute() {
    if (count == 0) {
        return false;
    }

    commands[count - 1]->Execute();

    return true;
}

CommandHistory::~CommandHistory() {
    delete[] commands;
}

Задатак 5.

На програмском језику C++ дефинисати:

  • класу Broj која садржи:
    • атрибут vrsta (char*)
    • атрибут vrednost (double)
    • јавну методу за поређење два броја (по вредности)
    • виртуелну јавну методу Print за приказ врсте и вредности броја на стандардни излаз,
    • заштићену виртуелну методу за постављање вредности броја,
    • виртуелну методу за враћање вредности броја.
  • класу RacionalanBroj изведену из класе Broj за представљање бројева облика \(\frac{a}{b}\), где су \(a\) и \(b\) цели бројеви.
  • класу KompleksanBroj изведену из класе Broj за представљање бројева облика \(a + j\cdot b\), а под вредношћу броја подразумева се његов модул.

У изведеним класама дефинисати приватне атрибуте којима је одређен одговарајући број и конструкторе који постављају одређене атрибуте.

У функцији main инстанцирати низ од 2018 показивача на објекте типа Broj, од којих 1009 указују на рационалне, а 1009 на комплексне бројеве. Вредности бројева или учитати из унапред дефинисане датотеке или их случајно генерисати. Сортирати бројеве у низу по вредности у опадајућем редоследу и уписати их у текстуалниу датотеку.

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

#include <fstream>
#include <random>

#include "Broj.h"
#include "KompleksanBroj.h"
#include "RacionalanBroj.h"

int main() {
    auto brojevi = new Broj*[2018];

    std::random_device rd;
    std::mt19937 mt(rd());
    std::uniform_real_distribution<double> realDist(-100, 100);
    std::uniform_int_distribution<int> intDist(-100, 100);

    int n = 0;
    for (int i = 0; i < 1009; i++) {
        brojevi[n++] = new RacionalanBroj(intDist(mt), intDist(mt));
        brojevi[n++] = new KompleksanBroj(realDist(mt), realDist(mt));
    }

    for (int i = 0; i < n - 1; i++) {
        for (int j = i + 1; j < n; j++) {
            if (brojevi[i]->Poredi(brojevi[j]) < 0) {
                auto temp = brojevi[i];
                brojevi[i] = brojevi[j];
                brojevi[j] = temp;
            }
        }
    }

    std::ofstream out("brojevi.txt");

    for (int i = 0; i < n; i++) {
        out << brojevi[i]->Vrednost() << std::endl;
    }

    out.close();

    delete brojevi;

    return 0;
}
#ifndef BROJ_H
#define BROJ_H


class Broj {
protected:
    char *vrsta;
    double vrednost;

    virtual void PostaviVrednost(double vrednost);

public:
    Broj(char *vrsta, double vrednost);

    int Poredi(const Broj *broj) const;

    virtual void Print();

    virtual double Vrednost();

    ~Broj();
};


#endif
#include "Broj.h"

#include <cstring>
#include <iostream>

Broj::Broj(char* vrsta, double vrednost) {
    this->vrsta = new char[strlen(vrsta) + 1];
    strcpy(this->vrsta, vrsta);
    this->vrednost = vrednost;
}

void Broj::PostaviVrednost(double vrednost) {
    this->vrednost = vrednost;
}

int Broj::Poredi(const Broj *broj) const {
    if (this->vrednost > broj->vrednost) {
        return 1;
    }

    if (this->vrednost < broj->vrednost) {
        return -1;
    }

    return 0;
}

void Broj::Print() {
    std::cout << this->vrsta << ": " << this->vrednost << std::endl;
}

double Broj::Vrednost() {
    return this->vrednost;
}

Broj::~Broj() {
    delete[] this->vrsta;
}
#ifndef RACIONALANBROJ_H
#define RACIONALANBROJ_H
#include "Broj.h"


class RacionalanBroj : public Broj {
private:
    int a;
    int b;

public:
    RacionalanBroj(int a, int b);

    void Print() override;
};


#endif
#include "RacionalanBroj.h"

#include <iostream>

RacionalanBroj::RacionalanBroj(int a, int b) : Broj(new char[]{"Racionalan broj"}, static_cast<double>(a) / b) {
    this->a = a;
    this->b = b;
}

void RacionalanBroj::Print() {
    std::cout << this->vrsta << ": " << this->a << "/" << this->b << std::endl;
}
#ifndef KOMPLEKSANBROJ_H
#define KOMPLEKSANBROJ_H

#include "Broj.h"


class KompleksanBroj : public Broj {
private:
    double a;
    double b;

public:
    KompleksanBroj(double a, double b);

    void Print() override;
};


#endif
#include "KompleksanBroj.h"

#include <cmath>
#include <iostream>

KompleksanBroj::KompleksanBroj(double a, double b) : Broj(new char[]{"Kompleksan broj"}, std::sqrt(pow(a, 2) + pow(b, 2))) {
    this->a = a;
    this->b = b;
}

void KompleksanBroj::Print() {
    std::cout << this->vrsta << ": " << this->a;

    if (this->b != 0) {
        std::cout << (this->b < 0 ? " - " : " + ") << "j ⋅ " << std::abs(this->b);
    }

    std::cout << std::endl;
}

Задатак 6.

На програмском језику C++ направити класу Window која као чланове има:

  • title - назив прозора,
  • state - стање прозора (отворен/затворен),
  • виртуалну методу draw() која исписује вредности параметара title и state,
  • методу open() - отварање прозора,
  • методу close() - затварање прозора.

При отварању и затварању прозора се модификује стање прозора (state). Из класе Window извести две класе: DialogWindow и DocumentWindow. Класа DialogWindow предефинише методу draw тако што исписује на екрану „DialogWindow nacrtan”, и има додатне две методе:

  • confirm() - затвара прозор и затим враћа вредност 1,
  • cancel() - затвара прозор и затим враћа вредност 0.

Класа DocumentWindow предефинише draw тако што исписује на екрану „DocumentWindow nacrtan”.

У функцији main дефинисати низ од 2018 показивача типа Window, инстанцирате по 1009 објеката класе DialogWindow и DocumentWindow и испробати све методе направљених класа. На крају сортирати све прозоре по називу и сортирани низ уписати у текстуалну датотеку.

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

#include <cstring>
#include <fstream>
#include <iostream>

#include "DialogWindow.h"
#include "DocumentWindow.h"
#include "Window.h"

char *randStr(int len) {
    char *str = new char[len + 1];
    for (int i = 0; i < len; i++) {
        str[i] = rand() % 26 + 97;
    }
    str[len] = '\0';
    return str;

}

int main() {
    auto windows = new Window*[2018];

    int n = 0;
    for (int i = 0; i < 1009; i++) {
        windows[n++] = new DialogWindow(randStr(10), (i + n) % 2 == 0 ? WindowState::opened : WindowState::closed);
        windows[n++] = new DocumentWindow(randStr(10), (i + n) % 6 == 0 ? WindowState::opened : WindowState::closed);
    }

    for (int i = 0; i < n; i++) {
        windows[i]->Draw();
        if (i % 2 == 0) {
            if (dynamic_cast<DialogWindow*>(windows[i]) != nullptr) {
                dynamic_cast<DialogWindow*>(windows[i])->Confirm();
            } else {
                windows[i]->Open();
            }
        }

        if (i % 6 == 0) {
            if (dynamic_cast<DialogWindow*>(windows[i]) != nullptr) {
                dynamic_cast<DialogWindow*>(windows[i])->Cancel();
            } else {
                windows[i]->Close();
            }
        }
    }

    for (int i = 0; i < n - 1; i++) {
        for (int j = i + 1; j < n; j++) {
            if (strcmp(windows[i]->Title(), windows[j]->Title()) > 0) {
                Window *tmp = windows[i];
                windows[i] = windows[j];
                windows[j] = tmp;
            }
        }
    }

    std::ofstream out("windows.txt");
    for (int i = 0; i < n; i++) {
        out << windows[i]->Title() << ": " << (windows[i]->State() == WindowState::opened ? "opened" : "closed") << std::endl;
    }

    out.close();

    delete[] windows;

    return 0;
}
#ifndef WINDOW_H
#define WINDOW_H

enum class WindowState {
    opened,
    closed,
};

class Window {
protected:
    char *title;
    WindowState state;

public:
    Window(const char *title, WindowState state);

    virtual void Draw();

    bool Open();

    bool Close();

    char *Title() const {
        return title;
    }

    WindowState State() const {
        return state;
    }

    ~Window();
};


#endif
#include "Window.h"

#include <cstring>
#include <iostream>

Window::Window(const char *title, WindowState state) {
    this->title = new char[strlen(title) + 1];
    strcpy(this->title, title);
    this->state = state;
}

void Window::Draw() {
    std::cout << title << ": " << (state == WindowState::opened ? "opened" : "closed") << std::endl;
}

bool Window::Open() {
    if (state == WindowState::closed) {
        state = WindowState::opened;
        return true;
    }

    return false;
}

bool Window::Close() {
    if (state == WindowState::opened) {
        state = WindowState::closed;
        return true;
    }

    return false;
}

Window::~Window() {
    delete[] title;
}
#ifndef DIALOGWINDOW_H
#define DIALOGWINDOW_H
#include "Window.h"


class DialogWindow : public Window {
public:
    DialogWindow(const char *title, WindowState state);

    void Draw() override;

    int Confirm();

    int Cancel();
};


#endif
#include "DialogWindow.h"

#include <iostream>

DialogWindow::DialogWindow(const char *title, WindowState state) : Window(title, state) {}

void DialogWindow::Draw() {
    Window::Draw();
    std::cout << "DialogWindow nacrtan" << std::endl;
}

int DialogWindow::Confirm() {
    Close();
    return 1;
}

int DialogWindow::Cancel() {
    Close();
    return 0;
}
#ifndef DOCUMENTWINDOW_H
#define DOCUMENTWINDOW_H
#include "Window.h"


class DocumentWindow : public Window {
public:
    DocumentWindow(const char *title, WindowState state);

    void Draw() override;
};


#endif
#include "DocumentWindow.h"

#include <iostream>

DocumentWindow::DocumentWindow(const char *title, WindowState state) : Window(title, state) {}

void DocumentWindow::Draw() {
    Window::Draw();
    std::cout << "DocumentWindow nacrtan" << std::endl;
}

Задатак 7.

На програмском језику C++ направити класу Artikal која као чланове има:

  • назив,
  • цену,
  • виртуалну методу showDescription() која исписује параметре назив и цена,
  • методу getPrice() која враћа цену артикла.

Из класе Artikal извести две класе: Laptop и Torba. Класа Laptop поседује следеће чланове:

  • opis (char*),
  • stanje (укључен-искључен),
  • предефинисану методу showDescription() која исписује на екрану naziv, cenu и opis,
  • методу turnOn() - модификује се стање и исписује се порука на екрану,
  • методу turnOff() - модификује се стање и исписује порука на екрану.

Класа Torba садржи следеће чланове:

  • атрибут sadrzaj - типа Artikal, показивач на артикал тренутно смештен у торби,
  • предефинисати методу showDescription() која исписује на екрану текст „Torba za Laptop računar” и након тога зове методу showDescription() за артикал смештен у торби,
  • методу put(Artikal &a) - симулација смештања артикла у торбу уколико је празна и исписује поруку да ли је артикал смештен или не,
  • методу remove() - симулира вађење артикла из торбе.

У функцији main инстанцирати низ од 2018 показивача типа Artikal и по 1009 објеката класе Laptop и Torba и испробати све методе обе класе. На крају, сортирати све производе по цени и резултат сортирања уписати у текстуалну датотеку.

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

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

#include "Artikal.h"
#include "Laptop.h"
#include "Torba.h"

char *randStr(int len) {
    char *str = new char[len + 1];
    for (int i = 0; i < len; i++) {
        str[i] = rand() % 26 + 97;
    }
    str[len] = '\0';
    return str;

}

int main() {
    auto artikli = new Artikal*[2018];

    std::random_device rd;
    std::mt19937 mt(rd());
    std::uniform_int_distribution<int> intDist(100, 20000);

    int n = 0;
    for (int i = 0; i < 1009; i++) {
        artikli[n++] = new Laptop(randStr(10), intDist(mt), randStr(30));
        artikli[n++] = new Torba(randStr(10), intDist(mt));

        if (i % 3 == 0) {
            dynamic_cast<Torba*>(artikli[n - 1])->Put(artikli[n - 2]);
        }
    }

    for (int i = 0; i < n; i++) {
        if (i % 9 == 0 && dynamic_cast<Torba*>(artikli[i]) != nullptr) {
            dynamic_cast<Torba*>(artikli[i])->ShowDescription();
            dynamic_cast<Torba*>(artikli[i])->Remove();
        }

        if (dynamic_cast<Laptop*>(artikli[i])) {
            dynamic_cast<Laptop*>(artikli[i])->ShowDescription();

            if (i % 3 == 0) {
                dynamic_cast<Laptop*>(artikli[i])->TurnOn();
            }

            if (i % 9 == 0) {
                dynamic_cast<Laptop*>(artikli[i])->TurnOff();
            }
        }
    }

    for (int i = 0; i < n - 1; i++) {
        for (int j = i + 1; j < n; j++) {
            if (artikli[i]->GetPrice() > artikli[j]->GetPrice()) {
                auto pom = artikli[i];
                artikli[i] = artikli[j];
                artikli[j] = pom;
            }
        }
    }

    std::ofstream outFile("artikli.txt");

    for (int i = 0; i < n; i++) {
        outFile << artikli[i]->GetPrice() << std::endl;
    }

    outFile.close();

    delete[] artikli;

    return 0;
}
#ifndef ARTIKAL_H
#define ARTIKAL_H


class Artikal {
protected:
    char *naziv;
    int cena;

public:
    Artikal(char *naziv, int cena);

    virtual void ShowDescription();

    int GetPrice();
};


#endif
#include "Artikal.h"

#include <cstring>
#include <iostream>

Artikal::Artikal(char *naziv, int cena) {
    this->naziv = new char[strlen(naziv) + 1];
    strcpy(this->naziv, naziv);
    this->cena = cena;
}

void Artikal::ShowDescription() {
    std::cout << "Naziv: " << this->naziv << std::endl;
    std::cout << "Cena: " << this->cena << std::endl;
}

int Artikal::GetPrice() {
    return this->cena;
}
#ifndef LAPTOP_H
#define LAPTOP_H
#include "Artikal.h"

enum class LaptopState {
    on,
    off
};

class Laptop : public Artikal {
private:
    char *opis;
    LaptopState stanje;

public:
    Laptop(char *naziv, int cena, char *opis);

    void ShowDescription() override;

    void TurnOn();

    void TurnOff();
};


#endif
#include "Laptop.h"

#include <cstring>
#include <iostream>

Laptop::Laptop(char *naziv, int cena, char *opis) : Artikal(naziv, cena) {
    this->opis = new char[strlen(opis) + 1];
    strcpy(this->opis, opis);
    this->stanje = LaptopState::off;
}

void Laptop::ShowDescription() {
    std::cout << this->naziv << " " << this->cena << " " << this->opis << std::endl;
}

void Laptop::TurnOn() {
    this->stanje = LaptopState::on;
}

void Laptop::TurnOff() {
    this->stanje = LaptopState::off;
}
#ifndef TORBA_H
#define TORBA_H
#include "Artikal.h"


class Torba : public Artikal {
private:
    Artikal *sadrzaj;

public:
    Torba(char *naziv, int cena);

    void ShowDescription() override;

    bool Put(Artikal *artikal);

    bool Remove();
};


#endif
#include "Torba.h"

#include <iostream>

Torba::Torba(char* naziv, int cena) : Artikal(naziv, cena) {}

void Torba::ShowDescription() {
    std::cout << "Torba za Laptop računar. ";

    if (this->sadrzaj == nullptr) {
        std::cout << "Prazna." << std::endl;
        return;
    }

    this->sadrzaj->ShowDescription();
}

bool Torba::Put(Artikal *artikal) {
    if (this->sadrzaj != nullptr) {
        std::cout << "Torba je puna!" << std::endl;
        return false;
    }

    this->sadrzaj = artikal;
    std::cout << "Artikal je uspešno smešten u torbi." << std::endl;

    return true;
}

bool Torba::Remove() {
    if (this->sadrzaj == nullptr) {
        std::cout << "Torba je prazna!" << std::endl;
        return false;
    }

    this->sadrzaj = nullptr;
    std::cout << "Artikal je uspešno izvađen iz torbe." << std::endl;

    return true;
}

Задатак 8.

На програмском језику C++ направити класу GeometrijskaSlika која садржи приватне атрибуте:

  • боја (дефинисана својим компонентама: R-црвено, G-зелено и B-плаво чије су вредности у опсегу 0–255),
  • тежиште (одређено x и y координатама).

Класа садржи следеће јавне чланице:

  • конструктор који иницијализује све приватне атрибуте,
  • методу за израчунавање растојања фигуре (њеног тежишта) од координатног почетка,
  • методу за транслирање фигуре за задати померај (дефинисан својим x и y компонентама),
  • виртуелну методу Show за приказ атрибута боја и тежиште на стандардни излаз,
  • заштићену виртуелну методу за израчунавање површине фигуре,
  • методу за испитивање да ли је фигура већа (по површини) од друге задате фигуре.

Направити и класе Krug (чији је приватни атрибут полупречник) и Kvadrat (чији је приватни атрибут стрница). У изведеним класама дефинисати конструкторе и методе за израчунавање површине. Предефинисати методе за приказ атрибута тако што ће пре приказа атрибута бити исписан тип фигуре, а после приказа атрибута родитељске класе приказати и атрибуте дефинисане у изведеним класама.

У функцији main инстанцирати по 2018 објеката класе Kvadrat и Krug у динамичкој зони меморије. Поставити све њихове атрибуте на случајне вредност из опсега 0–255. Након тога транслирати их за вектор \((a, b)\). За сваку фигуру одредити посебно \(a\) и \(b\) као случајно изабрану вредност из интервала \((-12{,}8, 12{,}8)\).

Сортирати све инстанциране фигуре по површини у неопадајућем редоследу и у текстуалну датотеку уписати све њихове атрибуте, површину и растојање од координатног почетка. Водити рачуна да се подаци о једној фигури уписују у један ред излазне датотеке.

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

#include <iostream>
#include <random>

#include "GeometrijskaSlika.h"
#include "Krug.h"
#include "Kvadrat.h"

int main() {
    auto figure = new GeometrijskaSlika*[2018];

    std::random_device rd;
    std::mt19937 mt(rd());
    std::uniform_int_distribution<short> shortDist(0, 255);
    std::uniform_real_distribution<double> doubleDist1(-100, 100);
    std::uniform_real_distribution<double> doubleDist2(-12.8, 12.8);

    int n = 0;
    for (int i = 0; i < 1009; i++) {
        figure[n++] = new Krug(shortDist(mt), shortDist(mt), shortDist(mt), doubleDist1(mt), doubleDist1(mt), doubleDist1(mt));
        figure[n++] = new Kvadrat(shortDist(mt), shortDist(mt), shortDist(mt), doubleDist1(mt), doubleDist1(mt), doubleDist1(mt));
    }

    for (int i = 0; i < n; i++) {
        figure[i]->Transliraj(doubleDist2(mt), doubleDist2(mt));
    }

    for (int i = 0; i < n - 1; i++) {
        for (int j = i + 1; j < n; j++) {
            if (figure[i]->Uporedi(figure[j]) > 0) {
                auto pom = figure[i];
                figure[i] = figure[j];
                figure[j] = pom;
            }
        }
    }

    std::ofstream out("figure.txt");

    for (int i = 0; i < n; i++) {
        out << figure[i];
    }

    delete[] figure;

    return 0;
}
#ifndef GEOMETRIJSKASLIKA_H
#define GEOMETRIJSKASLIKA_H
#include <fstream>

struct Boja {
    short r, g, b;
};

struct Vek2 {
    double x, y;
};

class GeometrijskaSlika {
private:
    Boja boja{};
    Vek2 teziste{};

protected:
    virtual double Povrsina();

public:
    GeometrijskaSlika(Boja boja, Vek2 teziste);

    GeometrijskaSlika(short r, short g, short b, double x, double y);

    double Rastojanje();

    void Transliraj(Vek2 pomeraj);

    void Transliraj(double x, double y);

    virtual void Show();

    int Uporedi(GeometrijskaSlika *figura);

    friend std::ostream &operator<<(std::ostream& out, GeometrijskaSlika* figura);
};


#endif
#include "GeometrijskaSlika.h"

#include <cmath>
#include <iostream>

GeometrijskaSlika::GeometrijskaSlika(Boja boja, Vek2 teziste) {
    this->boja = boja;
    this->teziste = teziste;
}

GeometrijskaSlika::GeometrijskaSlika(short r, short g, short b, double x, double y) {
    this->boja = {r, g, b};
    this->teziste = {x, y};
}

double GeometrijskaSlika::Rastojanje() {
    return sqrt(pow(teziste.x, 2) + pow(teziste.y, 2));
}

void GeometrijskaSlika::Transliraj(Vek2 pomeraj) {
    teziste.x += pomeraj.x;
    teziste.y += pomeraj.y;
}

void GeometrijskaSlika::Transliraj(double x, double y) {
    teziste.x += x;
    teziste.y += y;
}

void GeometrijskaSlika::Show() {
    std::cout << "(" << boja.r << ", " << boja.g << ", " << boja.b << "); (" << teziste.x << ", " << teziste.y << ")";
}

int GeometrijskaSlika::Uporedi(GeometrijskaSlika *figura) {
    if (this->Povrsina() > figura->Povrsina()) {
        return 1;
    }

    if (this->Povrsina() < figura->Povrsina()) {
        return -1;
    }

    return 0;
}

double GeometrijskaSlika::Povrsina() {
    return 0;
}

std::ostream &operator<<(std::ostream& out, GeometrijskaSlika* figura) {
    out << "(" << figura->boja.r << ", " << figura->boja.g << ", " << figura->boja.b << "); (" << figura->teziste.x << ", " << figura->teziste.y << "); " << figura->Povrsina()<< "; " << figura->Rastojanje() << std::endl;
    return out;
}
#ifndef KRUG_H
#define KRUG_H
#include "GeometrijskaSlika.h"


class Krug : public GeometrijskaSlika {
private:
    double poluprecnik;

public:
    Krug(Boja boja, Vek2 teziste, double poluprecnik);

    Krug(short r, short g, short b, double x, double y, double poluprecnik);

    double Povrsina() override;

    void Show() override;
};


#endif
#include "Krug.h"

#include <cmath>
#include <iostream>

Krug::Krug(Boja boja, Vek2 teziste, double poluprecnik) : GeometrijskaSlika(boja, teziste) {
    this->poluprecnik = poluprecnik;
}

Krug::Krug(short r, short g, short b, double x, double y, double poluprecnik) : GeometrijskaSlika(r, g, b, x, y) {
    this->poluprecnik = poluprecnik;
}

double Krug::Povrsina() {
    return std::pow(poluprecnik, 2) * M_PI;
}

void Krug::Show() {
    std::cout << "Krug: ";
    GeometrijskaSlika::Show();
    std::cout << "; r =" << poluprecnik << std::endl;
}
#ifndef KVADRAT_H
#define KVADRAT_H
#include "GeometrijskaSlika.h"


class Kvadrat : public GeometrijskaSlika {
private:
    double stranica;

public:
    Kvadrat(Boja boja, Vek2 teziste, double stranica);

    Kvadrat(short r, short g, short b, double x, double y, double stranica);

    double Povrsina() override;

    void Show() override;
};


#endif
#include "Kvadrat.h"

#include <cmath>
#include <iostream>

Kvadrat::Kvadrat(Boja boja, Vek2 teziste, double stranica) : GeometrijskaSlika(boja, teziste) {
    this->stranica = stranica;
}

Kvadrat::Kvadrat(short r, short g, short b, double x, double y, double stranica) : GeometrijskaSlika(r, g, b, x, y) {
    this->stranica = stranica;
}

double Kvadrat::Povrsina() {
    return std::pow(stranica, 2);
}

void Kvadrat::Show() {
    std::cout << "Kvadrat: ";
    GeometrijskaSlika::Show();
    std::cout << "; a =" << stranica << std::endl;
}

Задатак 9.

На програмском језику C++ направити:

  • Класу Displej која садржи:
    • заштићени податак cifra која представља хексадекадну цифру тренутно приказану на дисплеју,
    • виртуелну методу set која поставља вредност цифре. Ова метода треба да обезбеди да се невалидне вредности не прихвате,
    • методу reset која поставља цифуру на 0,
    • виртуелну методу increment која повећава садржај дисплеја за 1 по модулу 16,
    • виртуелну методу show која уписује садржај дисплеја на стандардни излаз.
  • Класу DekadniMatricniDisplej јавно изведену из класе Displej која садржи:
    • приватни податак - матрицу пиксела реда m×n у којој су нулама и јединицама представљене угашене и упаљене тачке на дисплеју које формирају цифру,
    • методу која ће унапред дефинисане садржајe матрице у складу са цифром која је тренутно приказана на дисплеју, учитати из датотеке,
    • предефинисати меотду set, да прихвата само декадне цифре,
    • предифинисати методу increment тако да садржај дисплеја повећава за 1 по модулу 10,
    • метода show треба да најпре позове на извршење методу show из основне класе, а затим испише садржај матрице пиксела на стандардни излаз.

У функцији main инстанцирати по један објекат класа Displej и DekadniMatricniDisplej. За оба објекта извршити следећу секвенцу акција:

  • поставити иницијалну вредност на 9,
  • извршити k инкрементирања (k мора бити веће од 50000),
  • позвати методу reset,
  • извршити k инкрементирања (k мора бити веће од 50000),

Након последњег, као и након сваког 2018-ог инкрементирања, позвати методу show за сваки од објеката.

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

#include <iostream>

#include "DekadniMatricniDisplej.h"
#include "Displej.h"

#define M 7
#define N 5

void Simulation(Displej *d1, DekadniMatricniDisplej *d2) {
    for (int k = 0; k < 100000; k++) {
        d1->Increment();
        d2->Increment();

        if (k % 2018 == 0) {
            d1->Show();
            d2->Show();
        }
    }
}

int main() {
    auto d1 = new Displej();
    auto d2 = new DekadniMatricniDisplej(M, N);

    d1->Set(9);
    d2->Set(9);

    Simulation(d1, d2);

    d1->Reset();
    d2->Reset();

    Simulation(d1, d2);

    delete d1;
    delete d2;

    return 0;
}
#ifndef DISPLEJ_H
#define DISPLEJ_H


class Displej {
protected:
    short cifra;

public:
    virtual bool Set(short val);

    void Reset();

    virtual void Increment();

    virtual void Show();
};


#endif
#include "Displej.h"

#include <iostream>

bool Displej::Set(short val) {
    if (val < 0 || val > 15) {
        return false;
    }

    cifra = val;
    return true;
}

void Displej::Reset() {
    cifra = 0;
}

void Displej::Increment() {
    cifra = (cifra + 1) % 16;
}

void Displej::Show() {
    std::cout << cifra << std::endl;
}
#ifndef DEKADNIMATRICNIDISPLEJ_H
#define DEKADNIMATRICNIDISPLEJ_H
#include "Displej.h"


class DekadniMatricniDisplej : public Displej {
private:
    bool **pikseli;
    int m, n;

    void UcitajPiksele();

public:
    DekadniMatricniDisplej(int m, int n);

    bool Set(short val) override;

    void Increment() override;

    void Show() override;

    ~DekadniMatricniDisplej();
};


#endif
#include "DekadniMatricniDisplej.h"

#include <fstream>
#include <iostream>
#include <string>

DekadniMatricniDisplej::DekadniMatricniDisplej(int m, int n) {
    this->m = m;
    this->n = n;
    pikseli = new bool *[m];
}

void DekadniMatricniDisplej::UcitajPiksele() {
    std::ifstream f("pikseli/" + std::to_string(cifra) + ".txt");

    for (int i = 0; i < m; i++) {
        pikseli[i] = new bool[n];

        for (int j = 0; j < n; j++) {
            int pixel;
            f >> pixel;
            pikseli[i][j] = pixel == 1;
        }
    }
}


bool DekadniMatricniDisplej::Set(short val) {
    if (val < 0 || val > 9) {
        return false;
    }

    cifra = val;
    return true;
}

void DekadniMatricniDisplej::Increment() {
    cifra = (cifra + 1) % 10;
}

void DekadniMatricniDisplej::Show() {
    Displej::Show();

    UcitajPiksele();

    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            std::cout << (pikseli[i][j] ? '*' : ' ');
        }
        std::cout << std::endl;
    }

    std::cout << std::endl;
}

DekadniMatricniDisplej::~DekadniMatricniDisplej() {
    for (int i = 0; i < m; i++) {
        delete[] pikseli[i];
    }

    delete[] pikseli;
}

Тест подаци

1
2
3
4
5
6
7
0 1 1 1 0
1 0 0 0 1
1 0 0 1 1
1 0 1 0 1
1 1 0 0 1
1 0 0 0 1
0 1 1 1 0
1
2
3
4
5
6
7
0 0 1 0 0
0 1 1 0 0
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0
1 1 1 1 1
1
2
3
4
5
6
7
0 1 1 1 0
1 0 0 0 1
0 0 0 0 1
0 0 0 1 0
0 0 1 0 0
0 1 0 0 0
1 1 1 1 1
1
2
3
4
5
6
7
0 1 1 1 0
1 0 0 0 1
0 0 0 0 1
0 0 1 1 0
0 0 0 0 1
1 0 0 0 1
0 1 1 1 0
1
2
3
4
5
6
7
0 0 0 1 0
0 0 1 1 0
0 1 0 1 0
1 0 0 1 0
1 1 1 1 1
0 0 0 1 0
0 0 0 1 0
1
2
3
4
5
6
7
1 1 1 1 1
1 0 0 0 0
1 1 1 1 0
0 0 0 0 1
0 0 0 0 1
1 0 0 0 1
0 1 1 1 0
1
2
3
4
5
6
7
0 1 1 1 0
1 0 0 0 1
1 0 0 0 0
1 1 1 1 0
1 0 0 0 1
1 0 0 0 1
0 1 1 1 0
1
2
3
4
5
6
7
1 1 1 1 1
0 0 0 0 1
0 0 0 1 0
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0
1
2
3
4
5
6
7
0 1 1 1 0
1 0 0 0 1
1 0 0 0 1
0 1 1 1 0
1 0 0 0 1
1 0 0 0 1
0 1 1 1 0
1
2
3
4
5
6
7
0 1 1 1 0
1 0 0 0 1
1 0 0 0 1
0 1 1 1 1
0 0 0 0 1
1 0 0 0 1
0 1 1 1 0