From 7b19cabee8b08478f31f6e4594ed28e1d04e153c Mon Sep 17 00:00:00 2001 From: Syndamia Date: Fri, 10 May 2024 10:10:21 +0300 Subject: [w11] Solved exercises --- week11/Exercise01/Set.hpp | 156 +++++++++++++++++++++++++++++++++ week11/Exercise02/Developer.h | 6 ++ week11/Exercise02/Employee.h | 10 +++ week11/Exercise02/Manager.cpp | 51 +++++++++++ week11/Exercise02/Manager.h | 18 ++++ week11/Exercise03/Camera.cpp | 8 ++ week11/Exercise03/Camera.h | 9 ++ week11/Exercise03/Electronics.cpp | 6 ++ week11/Exercise03/Electronics.h | 10 +++ week11/Exercise03/Laptop.cpp | 7 ++ week11/Exercise03/Laptop.h | 9 ++ week11/Exercise03/WashingMachine.cpp | 7 ++ week11/Exercise03/WashingMachine.h | 9 ++ week11/Exercise04/Name.cpp | 5 ++ week11/Exercise04/Name.h | 9 ++ week11/Exercise04/Street.cpp | 17 ++++ week11/Exercise04/Street.h | 9 ++ week11/Exercise04/String.cpp | 50 +++++++++++ week11/Exercise04/String.h | 18 ++++ week11/Exercise05/Counted.hpp | 64 ++++++++++++++ week11/Exercise06/TwoArray.hpp | 117 +++++++++++++++++++++++++ week11/Exercise07/DynamicArray.hpp | 90 +++++++++++++++++++ week11/Exercise07/Numbers.cpp | 44 ++++++++++ week11/Exercise07/Numbers.h | 14 +++ week11/Exercise07/String.cpp | 49 +++++++++++ week11/Exercise07/String.h | 13 +++ week11/Exercise08/Link.cpp | 54 ++++++++++++ week11/Exercise08/Link.h | 19 ++++ week11/Exercise08/Location.cpp | 5 ++ week11/Exercise08/Location.h | 10 +++ week11/Exercise08/Message.cpp | 55 ++++++++++++ week11/Exercise08/Message.h | 25 ++++++ week11/Exercise09/DirectConcat.hpp | 32 +++++++ week11/Exercise09/DirectConcat.hpp.gch | Bin 0 -> 2106544 bytes week11/Exercise09/MixedArray.hpp | 107 ++++++++++++++++++++++ week11/Exercise09/MixedConcat.hpp | 34 +++++++ week11/README.md | 152 ++++++++++++++++++++++++++++++++ 37 files changed, 1298 insertions(+) create mode 100644 week11/Exercise01/Set.hpp create mode 100644 week11/Exercise02/Developer.h create mode 100644 week11/Exercise02/Employee.h create mode 100644 week11/Exercise02/Manager.cpp create mode 100644 week11/Exercise02/Manager.h create mode 100644 week11/Exercise03/Camera.cpp create mode 100644 week11/Exercise03/Camera.h create mode 100644 week11/Exercise03/Electronics.cpp create mode 100644 week11/Exercise03/Electronics.h create mode 100644 week11/Exercise03/Laptop.cpp create mode 100644 week11/Exercise03/Laptop.h create mode 100644 week11/Exercise03/WashingMachine.cpp create mode 100644 week11/Exercise03/WashingMachine.h create mode 100644 week11/Exercise04/Name.cpp create mode 100644 week11/Exercise04/Name.h create mode 100644 week11/Exercise04/Street.cpp create mode 100644 week11/Exercise04/Street.h create mode 100644 week11/Exercise04/String.cpp create mode 100644 week11/Exercise04/String.h create mode 100644 week11/Exercise05/Counted.hpp create mode 100644 week11/Exercise06/TwoArray.hpp create mode 100644 week11/Exercise07/DynamicArray.hpp create mode 100644 week11/Exercise07/Numbers.cpp create mode 100644 week11/Exercise07/Numbers.h create mode 100644 week11/Exercise07/String.cpp create mode 100644 week11/Exercise07/String.h create mode 100644 week11/Exercise08/Link.cpp create mode 100644 week11/Exercise08/Link.h create mode 100644 week11/Exercise08/Location.cpp create mode 100644 week11/Exercise08/Location.h create mode 100644 week11/Exercise08/Message.cpp create mode 100644 week11/Exercise08/Message.h create mode 100644 week11/Exercise09/DirectConcat.hpp create mode 100644 week11/Exercise09/DirectConcat.hpp.gch create mode 100644 week11/Exercise09/MixedArray.hpp create mode 100644 week11/Exercise09/MixedConcat.hpp create mode 100644 week11/README.md (limited to 'week11') diff --git a/week11/Exercise01/Set.hpp b/week11/Exercise01/Set.hpp new file mode 100644 index 0000000..b83027f --- /dev/null +++ b/week11/Exercise01/Set.hpp @@ -0,0 +1,156 @@ +#pragma once + +template +class Set { + T* elements; + unsigned size; + + void free(); + void copyFrom(const Set& other); + +public: + Set(); + ~Set(); + Set(const Set& other); + Set& operator=(const Set& other); + Set(Set&& other); + Set& operator=(Set&& other); + + Set& operator+=(const Set& right); + template + friend Set operator+(const Set& left, const Set& right); + + Set& operator*=(const Set& right); + template + friend Set operator*(const Set& left, const Set& right); + + Set& operator-=(const Set& right); + template + friend Set operator-(const Set& left, const Set& right); +}; + +template +void Set::free() { + delete[] elements; +} + +template +void Set::copyFrom(const Set& other) { + this->size = other.size; + this->elements = new T[size]; + for (int i = 0; i < size; i++) { + this->elements[i] = other.elements[i]; + } +} + +template +Set::Set() { + elements = nullptr; + size = 0; +} + +template +Set::~Set() { + delete[] elements; +} + +template +Set::Set(const Set& other) { + copyFrom(other); +} + +template +Set& Set::operator=(const Set& other) { + if (this != &other) { + free(); + copyFrom(other); + } + return *this; +} + +template +Set::Set(Set&& other) { + this->size = other.size; + this->elements = other.elements; + other.elements = nullptr; +} + +template +Set& Set::operator=(Set&& other) { + if (this != &other) { + free(); + + this->size = other.size; + this->elements = other.elements; + other.elements = nullptr; + } + return *this; +} + +template +Set& Set::operator+=(const Set& right) { + T* biggerArray = new T[size + right.size]; + for (int i = 0; i < size; i++) { + biggerArray[i] = elements[i]; + } + for (int i = 0; i < right.size; i++) { + biggerArray[i+size] = right.elements[i]; + } + delete[] elements; + elements = biggerArray; + size += right.size; + + return *this; +} + +template +Set operator+(const Set& left, const Set& right) { + Set setUnion = left; + setUnion += right; + return setUnion; +} + +template +Set& Set::operator*=(const Set& right) { + T* commonArray = new T[size]; + unsigned commonCount = 0; + for (int i = 0; i < size; i++) { + for (int j = 0; j < right.size; j++) { + if (elements[i] == right.elements[j]) { + commonArray[commonCount++] = elements[i]; + break; + } + } + } + + size = commonCount; + delete[] elements; + elements = new T[size]; + for (int i = 0; i < size; i++) { + elements[i] = commonArray[i]; + } + delete[] commonArray; + + return *this; +} + +template +Set operator*(const Set& left, const Set& right) { + Set setIntersection = left; + setIntersection *= right; + return setIntersection; +} + +template +Set& Set::operator-=(const Set& right) { + Set complement = right * (*this); + *this = complement; + return *this; +} + +template +Set operator-(const Set& left, const Set& right) { + Set setComplement = left; + setComplement -= right; + return setComplement; +} diff --git a/week11/Exercise02/Developer.h b/week11/Exercise02/Developer.h new file mode 100644 index 0000000..997ab1e --- /dev/null +++ b/week11/Exercise02/Developer.h @@ -0,0 +1,6 @@ +#pragma once +#include "Employee.h" + +class Developer : Employee { + unsigned countProject; +}; diff --git a/week11/Exercise02/Employee.h b/week11/Exercise02/Employee.h new file mode 100644 index 0000000..7be3574 --- /dev/null +++ b/week11/Exercise02/Employee.h @@ -0,0 +1,10 @@ +#pragma once + +class Employee { + float paycheck; + +protected: + char name[512]; + char position[128]; + char department[64]; +}; diff --git a/week11/Exercise02/Manager.cpp b/week11/Exercise02/Manager.cpp new file mode 100644 index 0000000..c7ae6ff --- /dev/null +++ b/week11/Exercise02/Manager.cpp @@ -0,0 +1,51 @@ +#include "Manager.h" + +void Manager::free() { + delete[] managedTeam; +} + +void Manager::copyFrom(const Manager& other) { + this->length = other.length; + this->managedTeam = new Employee[other.length + 1]; + for (int i = 0; i < length; i++) { + this->managedTeam[i] = other.managedTeam[i]; + } +} + +Manager::Manager() { + this->managedTeam = nullptr; + this->length = 0; +} + +Manager::~Manager() { + free(); +} + +Manager::Manager(const Manager& other) { + copyFrom(other); +} + +Manager& Manager::operator=(const Manager& other) { + if (this != &other) { + free(); + copyFrom(other); + } + return *this; +} + +Manager::Manager(Manager&& other) { + this->length = other.length; + this->managedTeam = other.managedTeam; + other.managedTeam = nullptr; +} + +Manager& Manager::operator=(Manager&& other) { + if (this != &other) { + free(); + + this->length = other.length; + this->managedTeam = other.managedTeam; + other.managedTeam = nullptr; + } + return *this; +} diff --git a/week11/Exercise02/Manager.h b/week11/Exercise02/Manager.h new file mode 100644 index 0000000..a3a4c88 --- /dev/null +++ b/week11/Exercise02/Manager.h @@ -0,0 +1,18 @@ +#pragma once +#include "Employee.h" + +class Manager : Employee { + Employee* managedTeam; + unsigned length; + + void free(); + void copyFrom(const Manager& other); + +public: + Manager(); + ~Manager(); + Manager(const Manager& other); + Manager& operator=(const Manager& other); + Manager(Manager&& other); + Manager& operator=(Manager&& other); +}; diff --git a/week11/Exercise03/Camera.cpp b/week11/Exercise03/Camera.cpp new file mode 100644 index 0000000..b56a702 --- /dev/null +++ b/week11/Exercise03/Camera.cpp @@ -0,0 +1,8 @@ +#include "Camera.h" +#include "Electronics.h" +#include + +void Camera::Print() { + Electroics::Print(); + std::cout << ' ' << resolution; +} diff --git a/week11/Exercise03/Camera.h b/week11/Exercise03/Camera.h new file mode 100644 index 0000000..d9e480f --- /dev/null +++ b/week11/Exercise03/Camera.h @@ -0,0 +1,9 @@ +#pragma once +#include "Electronics.h" + +class Camera : Electronics { + float resolution; + +public: + virtual void Print() override; +}; diff --git a/week11/Exercise03/Electronics.cpp b/week11/Exercise03/Electronics.cpp new file mode 100644 index 0000000..73be261 --- /dev/null +++ b/week11/Exercise03/Electronics.cpp @@ -0,0 +1,6 @@ +#include "Electronics.h" +#include + +void Electroics::Print() { + std::cout << model << ' ' << needsVolts << ' ' << needsAmps; +} diff --git a/week11/Exercise03/Electronics.h b/week11/Exercise03/Electronics.h new file mode 100644 index 0000000..9f3d849 --- /dev/null +++ b/week11/Exercise03/Electronics.h @@ -0,0 +1,10 @@ +#pragma once + +class Electroics { + char model[256]; + float needsVolts; + float needsAmps; + +public: + virtual void Print(); +}; diff --git a/week11/Exercise03/Laptop.cpp b/week11/Exercise03/Laptop.cpp new file mode 100644 index 0000000..5c2ea87 --- /dev/null +++ b/week11/Exercise03/Laptop.cpp @@ -0,0 +1,7 @@ +#include "Laptop.h" +#include + +void Laptop::Print() { + Electroics::Print(); + std::cout << ' ' << screenSize; +} diff --git a/week11/Exercise03/Laptop.h b/week11/Exercise03/Laptop.h new file mode 100644 index 0000000..19b0bd5 --- /dev/null +++ b/week11/Exercise03/Laptop.h @@ -0,0 +1,9 @@ +#pragma once +#include "Electronics.h" + +class Laptop : Electronics { + float screenSize; + +public: + virtual void Print() override; +}; diff --git a/week11/Exercise03/WashingMachine.cpp b/week11/Exercise03/WashingMachine.cpp new file mode 100644 index 0000000..18caa5f --- /dev/null +++ b/week11/Exercise03/WashingMachine.cpp @@ -0,0 +1,7 @@ +#include "WashingMachine.h" +#include + +void WashingMachine::Print() { + Electroics::Print(); + std::cout << ' ' << maxLaundryWeight; +} diff --git a/week11/Exercise03/WashingMachine.h b/week11/Exercise03/WashingMachine.h new file mode 100644 index 0000000..8915393 --- /dev/null +++ b/week11/Exercise03/WashingMachine.h @@ -0,0 +1,9 @@ +#pragma once +#include "Electronics.h" + +class WashingMachine : Electronics { + unsigned maxLaundryWeight; + +public: + virtual void Print() override; +}; diff --git a/week11/Exercise04/Name.cpp b/week11/Exercise04/Name.cpp new file mode 100644 index 0000000..c12dfe7 --- /dev/null +++ b/week11/Exercise04/Name.cpp @@ -0,0 +1,5 @@ +#include "Name.h" + +unsigned Name::Length() { + return String::Length() * nameNumber; +} diff --git a/week11/Exercise04/Name.h b/week11/Exercise04/Name.h new file mode 100644 index 0000000..3120dd7 --- /dev/null +++ b/week11/Exercise04/Name.h @@ -0,0 +1,9 @@ +#pragma once +#include "String.h" + +class Name : public String { + unsigned nameNumber; + +public: + virtual unsigned Length() override; +}; diff --git a/week11/Exercise04/Street.cpp b/week11/Exercise04/Street.cpp new file mode 100644 index 0000000..8cc6905 --- /dev/null +++ b/week11/Exercise04/Street.cpp @@ -0,0 +1,17 @@ +#include "Street.h" + +unsigned numberLength(unsigned num) { + if (num == 0) return 1; + + unsigned len = 0; + while (num != 0) { + len++; + num /= 10; + } + + return len; +} + +unsigned Street::Length() { + return String::Length() + numberLength(streetNumber); +} diff --git a/week11/Exercise04/Street.h b/week11/Exercise04/Street.h new file mode 100644 index 0000000..279198e --- /dev/null +++ b/week11/Exercise04/Street.h @@ -0,0 +1,9 @@ +#pragma once +#include "String.h" + +class Street : public String { + unsigned streetNumber; + +public: + virtual unsigned Length() override; +}; diff --git a/week11/Exercise04/String.cpp b/week11/Exercise04/String.cpp new file mode 100644 index 0000000..e9cdd94 --- /dev/null +++ b/week11/Exercise04/String.cpp @@ -0,0 +1,50 @@ +#include "String.h" +#include + +void String::free() { + delete[] str; +} + +void String::copyFrom(const String& other) { + this->str = new char[strlen(other.str) + 1]; + strcpy(this->str, other.str); +} + +String::String() { + this->str = nullptr; +} + +String::~String() { + free(); +} + +String::String(const String& other) { + copyFrom(other); +} + +String& String::operator=(const String& other) { + if (this != &other) { + free(); + copyFrom(other); + } + return *this; +} + +String::String(String&& other) { + this->str = other.str; + other.str = nullptr; +} + +String& String::operator=(String&& other) { + if (this != &other) { + free(); + + this->str = other.str; + other.str = nullptr; + } + return *this; +} + +unsigned String::Length() { + return strlen(str); +} diff --git a/week11/Exercise04/String.h b/week11/Exercise04/String.h new file mode 100644 index 0000000..13481a0 --- /dev/null +++ b/week11/Exercise04/String.h @@ -0,0 +1,18 @@ +#pragma once + +class String { + char *str; + + void free(); + void copyFrom(const String& other); + +public: + String(); + ~String(); + String(const String& other); + String& operator=(const String& other); + String(String&& other); + String& operator=(String&& other); + + virtual unsigned Length(); +}; diff --git a/week11/Exercise05/Counted.hpp b/week11/Exercise05/Counted.hpp new file mode 100644 index 0000000..fe705ab --- /dev/null +++ b/week11/Exercise05/Counted.hpp @@ -0,0 +1,64 @@ +#pragma once + +template +class Counted { + T elem; + unsigned count; + +public: + T& GetElem(); + unsigned GetCount(); + + Counted& operator++(); + Counted operator++(int); + Counted& operator--(); + Counted operator--(int); + Counted& operator+=(int countChange); + Counted& operator-=(int countChange); +}; + +template +T& Counted::GetElem() { + return elem; +} + +template +unsigned Counted::GetCount() { + return count; +} + +template +Counted& Counted::operator++() { + ++count; + return *this; +} + +template +Counted Counted::operator++(int) { + count++; + return *this; +} + +template +Counted& Counted::operator--() { + --count; + return *this; +} + +template +Counted Counted::operator--(int) { + count--; + return *this; +} + +template +Counted& Counted::operator+=(int countChange) { + count += countChange; + return *this; +} + +template +Counted& Counted::operator-=(int countChange) { + count -= countChange; + return *this; +} diff --git a/week11/Exercise06/TwoArray.hpp b/week11/Exercise06/TwoArray.hpp new file mode 100644 index 0000000..62ff2c0 --- /dev/null +++ b/week11/Exercise06/TwoArray.hpp @@ -0,0 +1,117 @@ +#pragma once + +template +class TwoArray { + T* first; + U* second; + unsigned allocated; + unsigned size; + + void free(); + void copyFrom(const TwoArray& other); + +public: + TwoArray(); + ~TwoArray(); + TwoArray(const TwoArray& other); + TwoArray& operator=(const TwoArray& other); + TwoArray(TwoArray&& other); + TwoArray& operator=(TwoArray&& other); + + T& operator[](int index); + const T& operator[](int index) const; + U& operator()(int index); + const U& operator()(int index) const; +}; + +template +void TwoArray::free() { + delete[] first; + delete[] second; +} + +template +void TwoArray::copyFrom(const TwoArray& other) { + this->size = other.size; + this->allocated = other.allocated; + first = new T[allocated]; + second = new U[allocated]; + for (int i = 0; i < size; i++) { + first[i] = other.first[i]; + second[i] = other.second[i]; + } +} + +template +TwoArray::TwoArray() { + first = second = nullptr; + size = allocated = 0; +} + +template +TwoArray::~TwoArray() { + free(); +} + +template +TwoArray::TwoArray(const TwoArray& other) { + copyFrom(other); +} + +template +TwoArray& TwoArray::operator=(const TwoArray& other) { + if (this != &other) { + free(); + copyFrom(other); + } + return *this; +} + +template +TwoArray::TwoArray(TwoArray&& other) { + this->first = other.first; + other.first = nullptr; + this->second = other.second; + other.second = nullptr; + this->allocated = other.allocated; + this->size = other.size; +} + +template +TwoArray& TwoArray::operator=(TwoArray&& other) { + if (this != &other) { + free(); + + this->first = other.first; + other.first = nullptr; + this->second = other.second; + other.second = nullptr; + this->allocated = other.allocated; + this->size = other.size; + } + return *this; +} + +template +T& TwoArray::operator[](int index) { + if (index < 0 || index >= size) throw "Invalid index!"; + return first[index]; +} + +template +const T& TwoArray::operator[](int index) const { + if (index < 0 || index >= size) throw "Invalid index!"; + return first[index]; +} + +template +U& TwoArray::operator()(int index) { + if (index < 0 || index >= size) throw "Invalid index!"; + return second[index]; +} + +template +const U& TwoArray::operator()(int index) const { + if (index < 0 || index >= size) throw "Invalid index!"; + return second[index]; +} diff --git a/week11/Exercise07/DynamicArray.hpp b/week11/Exercise07/DynamicArray.hpp new file mode 100644 index 0000000..b7d8fb7 --- /dev/null +++ b/week11/Exercise07/DynamicArray.hpp @@ -0,0 +1,90 @@ +#pragma once + +template +class DynamicArray { + void free(); + void copyFrom(const DynamicArray& other); + +protected: + T* elems; + unsigned allocated; + unsigned size; + +public: + DynamicArray(); + virtual ~DynamicArray(); + DynamicArray(const DynamicArray& other); + DynamicArray& operator=(const DynamicArray& other); + DynamicArray(DynamicArray&& other); + DynamicArray& operator=(DynamicArray&& other); + + virtual T& operator[](int index) = 0; + virtual const T& operator[](int index) const = 0; + // Отговорът е не, не можем да използваме оператор += в полморфна йерархия + // Понеже String и Numbers не са шаблонни, а използват конкретна "инстанция" на шаблонния клас + // тогава полиморфно += би означавало += между разногласни типове, което няма как да стане (добре). + virtual DynamicArray& operator+=(const DynamicArray& other) = 0; +}; + +template +void DynamicArray::free() { + delete[] elems; +} + +template +void DynamicArray::copyFrom(const DynamicArray& other) { + this->size = other.size; + this->allocated = other.allocated; + elems = new T[allocated]; + for (int i = 0; i < size; i++) { + elems[i] = other.elems[i]; + } +} + +template +DynamicArray::DynamicArray() { + elems = nullptr; + size = allocated = 0; +} + +template +DynamicArray::~DynamicArray() { + free(); +} + +template +DynamicArray::DynamicArray(const DynamicArray& other) { + copyFrom(other); +} + +template +DynamicArray& DynamicArray::operator=(const DynamicArray& other) { + if (this != &other) { + free(); + copyFrom(other); + } + return *this; +} + +template +DynamicArray::DynamicArray(DynamicArray&& other) { + this->elems = other.elems; + other.elems = nullptr; + this->second = other.second; + other.second = nullptr; + this->allocated = other.allocated; + this->size = other.size; +} + +template +DynamicArray& DynamicArray::operator=(DynamicArray&& other) { + if (this != &other) { + free(); + + this->elems = other.elems; + other.elems = nullptr; + this->allocated = other.allocated; + this->size = other.size; + } + return *this; +} diff --git a/week11/Exercise07/Numbers.cpp b/week11/Exercise07/Numbers.cpp new file mode 100644 index 0000000..db8f218 --- /dev/null +++ b/week11/Exercise07/Numbers.cpp @@ -0,0 +1,44 @@ +#include "Numbers.h" +#include "DynamicArray.hpp" + +int& Numbers::operator[](int index) { + if (index >= size) throw "Index out of bounds"; + + for (int i = 0; i < size; i++) { + if (elems[i] < index) { + return elems[i]; + } + } + return elems[0]; +} + +const int& Numbers::operator[](int index) const { + if (index >= size) throw "Index out of bounds"; + + for (int i = 0; i < size; i++) { + if (elems[i] < index) { + return elems[i]; + } + } + return elems[0]; +} + +Numbers& Numbers::operator+=(const Numbers& other) { + int* biggerElems = new int[other.allocated + allocated]; + for (int i = 0; i < other.size; i++) { + biggerElems[i] = other.elems[i]; + } + for (int i = 0; i < size; i++) { + biggerElems[other.size + i] = elems[i]; + } + delete[] elems; + elems = biggerElems; + size += other.size; + allocated += other.allocated; + + return *this; +} + +DynamicArray& Numbers::operator+=(const DynamicArray& other) { + return *this += (const Numbers&)other; +} diff --git a/week11/Exercise07/Numbers.h b/week11/Exercise07/Numbers.h new file mode 100644 index 0000000..1219ab0 --- /dev/null +++ b/week11/Exercise07/Numbers.h @@ -0,0 +1,14 @@ +#pragma once +#include "DynamicArray.hpp" + +class Numbers : DynamicArray { + // Не можем да имаме полиморфно += (виж DynamicArray.hpp), но пак трябва да го имплементираме + // по някакъв начин. + virtual DynamicArray& operator+=(const DynamicArray& other) override; + +public: + virtual int& operator[](int index) override; + virtual const int& operator[](int index) const override; + Numbers& operator+=(const Numbers& other); +}; + diff --git a/week11/Exercise07/String.cpp b/week11/Exercise07/String.cpp new file mode 100644 index 0000000..8406f3c --- /dev/null +++ b/week11/Exercise07/String.cpp @@ -0,0 +1,49 @@ +#include "String.h" +#include + +char& String::operator[](int index) { + if (index <= 1) throw "Invalid index"; + + for (int i = 0; i < size; i++) { + if ('A' <= elems[i] && elems[i] <= 'Z') { + index--; + if (index == 0) { + return elems[i]; + } + } + } + return elems[size-1]; +} + +const char& String::operator[](int index) const { + if (index <= 1) throw "Invalid index"; + + for (int i = 0; i < size; i++) { + if ('A' <= elems[i] && elems[i] <= 'Z') { + index--; + if (index == 0) { + return elems[i]; + } + } + } + return elems[size-1]; +} + +String& String::operator+=(const String& other) { + char* biggerStr = new char[allocated + other.allocated]; + for (int i = 0; i < size; i++) { + biggerStr[i] = elems[i]; + } + for (int i = 0; i < other.size; i++) { + biggerStr[size + i] = other.elems[i]; + } + delete[] elems; + elems = biggerStr; + allocated += other.allocated; + size += other.size; + return *this; +} + +DynamicArray& String::operator+=(const DynamicArray& other) { + return *this += (const String&)other; +} diff --git a/week11/Exercise07/String.h b/week11/Exercise07/String.h new file mode 100644 index 0000000..d34555a --- /dev/null +++ b/week11/Exercise07/String.h @@ -0,0 +1,13 @@ +#pragma once +#include "DynamicArray.hpp" + +class String : DynamicArray { + // Не можем да имаме полиморфно += (виж DynamicArray.hpp), но пак трябва да го имплементираме + // по някакъв начин. + virtual DynamicArray& operator+=(const DynamicArray& other) override; + +public: + virtual char& operator[](int index) override; + virtual const char& operator[](int index) const override; + String& operator+=(const String& other); +}; diff --git a/week11/Exercise08/Link.cpp b/week11/Exercise08/Link.cpp new file mode 100644 index 0000000..d9941d5 --- /dev/null +++ b/week11/Exercise08/Link.cpp @@ -0,0 +1,54 @@ +#include "Link.h" +#include + +void Link::free() { + delete[] textMessage; + delete[] address; +} + +void Link::copyFrom(const Link& other) { + this->address = new char[strlen(other.address) + 1]; + strcpy(this->address, other.address); +} + +Link::Link() : Message() { + this->address = nullptr; +} + +Link::~Link() { + free(); +} + +Link::Link(const Link& other) : Message(other) { + copyFrom(other); +} + +Link& Link::operator=(const Link& other) { + if (this != &other) { + Message::operator=(other); + free(); + copyFrom(other); + } + return *this; +} + +Link::Link(Link&& other) { + Message::operator=(std::move(other)); + this->address = other.address; + other.address = nullptr; +} + +Link& Link::operator=(Link&& other) { + if (this != &other) { + free(); + + Message::operator=(std::move(other)); + this->address = other.address; + other.address = nullptr; + } + return *this; +} + +unsigned Link::size() { + return (Length() + 1) + (strlen(address) + 1); +} diff --git a/week11/Exercise08/Link.h b/week11/Exercise08/Link.h new file mode 100644 index 0000000..4acb312 --- /dev/null +++ b/week11/Exercise08/Link.h @@ -0,0 +1,19 @@ +#pragma once +#include "Message.h" + +class Link : public Message { + char* address; + + void free(); + void copyFrom(const Link& other); + +public: + Link(); + virtual ~Link() override; + Link(const Link& other); + Link& operator=(const Link& other); + Link(Link&& other); + Link& operator=(Link&& other); + + virtual unsigned size() override; +}; diff --git a/week11/Exercise08/Location.cpp b/week11/Exercise08/Location.cpp new file mode 100644 index 0000000..c63f470 --- /dev/null +++ b/week11/Exercise08/Location.cpp @@ -0,0 +1,5 @@ +#include "Location.h" + +unsigned Location::size() { + return (Length() + 1) + sizeof(lattitude) + sizeof(longitude); +} diff --git a/week11/Exercise08/Location.h b/week11/Exercise08/Location.h new file mode 100644 index 0000000..fbbe7a3 --- /dev/null +++ b/week11/Exercise08/Location.h @@ -0,0 +1,10 @@ +#pragma once +#include "Message.h" + +class Location : public Message { + float longitude; + float lattitude; + +public: + virtual unsigned size() override; +}; diff --git a/week11/Exercise08/Message.cpp b/week11/Exercise08/Message.cpp new file mode 100644 index 0000000..12c91e9 --- /dev/null +++ b/week11/Exercise08/Message.cpp @@ -0,0 +1,55 @@ +#include "Message.h" +#include +#include + +void Message::free() { + delete[] textMessage; +} + +void Message::copyFrom(const Message& other) { + this->textMessage = new char[strlen(other.textMessage) + 1]; + strcpy(this->textMessage, other.textMessage); +} + +Message::Message() { + this->textMessage = nullptr; +} + +Message::~Message() { + free(); +} + +Message::Message(const Message& other) { + copyFrom(other); +} + +Message& Message::operator=(const Message& other) { + if (this != &other) { + free(); + copyFrom(other); + } + return *this; +} + +Message::Message(Message&& other) { + this->textMessage = other.textMessage; + other.textMessage = nullptr; +} + +Message& Message::operator=(Message&& other) { + if (this != &other) { + free(); + + this->textMessage = other.textMessage; + other.textMessage = nullptr; + } + return *this; +} + +unsigned Message::Length() { + return strlen(textMessage); +} + +std::ostream& operator<<(std::ostream& ostr, const Message& obj) { + return ostr << obj.textMessage; +} diff --git a/week11/Exercise08/Message.h b/week11/Exercise08/Message.h new file mode 100644 index 0000000..2048263 --- /dev/null +++ b/week11/Exercise08/Message.h @@ -0,0 +1,25 @@ +#pragma once +#include + +class Message { + void copyFrom(const Message& other); + void free(); + +protected: + char* textMessage; + +public: + Message(); + virtual ~Message(); + Message(const Message& other); + Message& operator=(const Message& other); + Message(Message&& other); + Message& operator=(Message&& other); + + unsigned Length(); + // Отговорът е не, няма разлика между operator<< на трите класа + // В условието е казано, че текстовото съобщение се показва на екрана, но не е казано че другите данни се + friend std::ostream& operator<<(std::ostream& ostr, const Message& obj); + + virtual unsigned size() = 0; +}; diff --git a/week11/Exercise09/DirectConcat.hpp b/week11/Exercise09/DirectConcat.hpp new file mode 100644 index 0000000..53f420b --- /dev/null +++ b/week11/Exercise09/DirectConcat.hpp @@ -0,0 +1,32 @@ +#pragma once +#include "MixedArray.hpp" + +template +class DirectConcat : public MixedArray { +public: + virtual MixedArray* operator+=(const MixedArray* other) override; +}; + +template +MixedArray* DirectConcat::operator+=(const MixedArray* other) { + T* biggerFirst = new T[this->allocated + other->allocated]; + U* biggerSecond = new U[this->allocated + other->allocated]; + + for (int i = 0; i < this->size; i++) { + biggerFirst[i] = this->first[i]; + biggerSecond[i] = this->second[i]; + } + for (int i = 0; i < other->size; i++) { + biggerFirst[this->size + i] = other->first[i]; + biggerSecond[this->size + i] = other->second[i]; + } + + delete[] this->first; + this->first = biggerFirst; + delete[] this->second; + this->second = biggerSecond; + this->allocated += other->allocated; + this->size += other->size; + + return this; +} diff --git a/week11/Exercise09/DirectConcat.hpp.gch b/week11/Exercise09/DirectConcat.hpp.gch new file mode 100644 index 0000000..d7e6e3f Binary files /dev/null and b/week11/Exercise09/DirectConcat.hpp.gch differ diff --git a/week11/Exercise09/MixedArray.hpp b/week11/Exercise09/MixedArray.hpp new file mode 100644 index 0000000..096a227 --- /dev/null +++ b/week11/Exercise09/MixedArray.hpp @@ -0,0 +1,107 @@ +#pragma once + +template +class MixedArray { + void free(); + void copyFrom(const MixedArray& other); + +protected: + T* first; + U* second; + unsigned allocated; + unsigned size; + +public: + MixedArray(); + virtual ~MixedArray(); + MixedArray(const MixedArray& other); + MixedArray& operator=(const MixedArray& other); + MixedArray(MixedArray&& other); + MixedArray& operator=(MixedArray&& other); + + void At(int index, T*& valueFirst, U*& valueSecond); + + virtual MixedArray* operator+=(MixedArray* other) = 0; +}; + +template +void MixedArray::free() { + delete[] first; + delete[] second; +} + +template +void MixedArray::copyFrom(const MixedArray& other) { + this->size = other.size; + this->allocated = other.allocated; + first = new T[allocated]; + second = new U[allocated]; + for (int i = 0; i < size; i++) { + first[i] = other.first[i]; + second[i] = other.second[i]; + } +} + +template +MixedArray::MixedArray() { + first = second = nullptr; + size = allocated = 0; +} + +template +MixedArray::~MixedArray() { + free(); +} + +template +MixedArray::MixedArray(const MixedArray& other) { + copyFrom(other); +} + +template +MixedArray& MixedArray::operator=(const MixedArray& other) { + if (this != &other) { + free(); + copyFrom(other); + } + return *this; +} + +template +MixedArray::MixedArray(MixedArray&& other) { + this->first = other.first; + other.first = nullptr; + this->second = other.second; + other.second = nullptr; + this->allocated = other.allocated; + this->size = other.size; +} + +template +MixedArray& MixedArray::operator=(MixedArray&& other) { + if (this != &other) { + free(); + + this->first = other.first; + other.first = nullptr; + this->second = other.second; + other.second = nullptr; + this->allocated = other.allocated; + this->size = other.size; + } + return *this; +} + +template +void MixedArray::At(int index, T*& valueFirst, U*& valueSecond) { + if (index < 0) throw "Index out of bounds!"; + + if (index % 2 == 0) { + valueFirst = *first[index / 2]; + valueSecond = nullptr; + } + else { + valueFirst = nullptr; + valueSecond = *second[(index - 1) / 2]; + } +} diff --git a/week11/Exercise09/MixedConcat.hpp b/week11/Exercise09/MixedConcat.hpp new file mode 100644 index 0000000..2b43f80 --- /dev/null +++ b/week11/Exercise09/MixedConcat.hpp @@ -0,0 +1,34 @@ +#pragma once +#include "MixedArray.hpp" + +template +class MixedConcat : public MixedArray { +public: + virtual MixedArray* operator+=(const MixedArray* other) override; +}; + +template +MixedArray* MixedConcat::operator+=(const MixedArray* other) { + T* biggerFirst = new T[this->allocated + other->allocated]; + U* biggerSecond = new U[this->allocated + other->allocated]; + + for (int i = 0; i < this->size + other->size; i++) { + if (i % 2 == 0) { + biggerFirst[i] = this->first[i / 2]; + biggerSecond[i] = this->second[i / 2]; + } + else { + biggerFirst[i] = other->first[(i - 1) / 2]; + biggerSecond[i] = other->second[(i - 1) / 2]; + } + } + + delete[] this->first; + this->first = biggerFirst; + delete[] this->second; + this->second = biggerSecond; + this->allocated += other->allocated; + this->size += other->size; + + return this; +} diff --git a/week11/README.md b/week11/README.md new file mode 100644 index 0000000..fe4bfa5 --- /dev/null +++ b/week11/README.md @@ -0,0 +1,152 @@ +# Задачи - ООП, Седмица 11, 09.05.2024 + +*Този файл е копие на задачите от: [syndamia.com/teaching/oop-2023/week11](https://syndamia.com/teaching/oop-2023/week11)* + +## Преговорни + +&:warn Моля, не отделяйте на преговорните задачи повече от 30мин + +&:important Ако за даден клас е имплементиран деструктор, тогава в него и всичките му деца трябва да добавите `virtual` пред деструктора! + +### Задача 1 - Шаблони и оператори + +Реализирайте шаблонен клас множество, който запазва фиксиран брой елементи от подаден тип. +Реализирайте голяма петица и оператори: + +- +, += които действат като обединение +- \*, \*= които действат като сечение +- -, -= които действат като допълнение + +### Задача 2 - Наследяване + +Реализирайте клас Employee, съхраняващ име на човек, позиция и департамент като низове със съответно дължина 512, 128 и 64, заедно със заплата като число с плаваща запетая. + +Реализирайте негов наследник Manager, който допълнително пази масив с фиксиран размер от Employee. + +Реализирайте наследника на Employee, Developer, който допълнително пази брой проекти върху който работи. + +Наследниците не могат да достъпят заплатата, но трябва да могат да достъпят другите данни на Employee. + +## Лесни + +### Задача 3 + + + +Реализирайте клас Electronics, който съдържа модел (низ с максимална дължина от 255 знака), needsVolts и needsAmps (стойности с плаваща запетая). + +Имплементирайте негови наследници: + +- Laptop, който допълнително съхранява размер на екрана като число с плаваща запетая +- WashingMachine, който допълнително запазва максимално тегло на прането, като цяло неотрицателно число +- Camera, която допълнително запазва резолюция като число с плаваща запетая (в мегапиксели) + +За всеки клас реализирайте член-функция Print, която изкарва всички данни на екрана. + +&:question Чрез статично или динамично свързване сте имплементирали Print? Каква е разликата? + +### Задача 4 + + + +Реализирайте клас String, който запазва динамично-заделен масив. + +Имплементирайте негов наследник Name, който допълнително запазва число: номер на името (първо име, бащино име (второ име), фамилия (трето име)). + +Имплементирайте втори наследник на String, Street, който запазва и число: номер на улицата. + +Във всеки клас имплементирайте голяма петица, член-функция length, като в String връща дължината на низа, в Name връща дължината на името умножена по номера си и в Street връща дължината на името на улицата плюс броя цифри в номера на улицата. + +### Задача 5 + + + +Реализирайте шаблонен клас Counted, който запазва елемент от подаден тип и неговата бройка (цяло неотрицателно число). +Имплементирайте оператори ++, --, +=, -=, които променят бройката. + +### Задача 6 + + + +Реализирайте шаблонен клас TwoArray, който запазва два динамично-заделени масива с подадени типове. +Масивите не могат да се оразмеряват и имат еднаква дължина. + +Имплементирайте голяма петица, оператор [], който по подаден индекс връща елемент от първия масив, и оператор (), който по подаден индекс връща елемент от втория масив. + +### Задача 7 + + + +Реализирайте абстрактен клас DynamicArray, който задължава наследниците да имплементират оператор [], оператор += и оператор +. + +Реализирайте негови наследници String, който имплементира динамично-заделен масив от букви, и Numbers, който имплементира динамично-заделен масив от числа. +Имплементирайте голяма петица. + +### Задача 8 + + + +Имплементирайте абстрактен клас Message, който съдържа динамично-заделен низ (текстово съобщение) и задължава наследниците да имплементират метод size, който връща общия размер на всички данни в байтове. + +Реализирайте негов наследник Link (хипервръзка), който запазва и втори динамично-заделен низ, запазващ адресът към който линкът сочи. + +Реализирайте втори негов наследник Location, чието текстово съдържание е адрес, и който допълнително запазва две стойности с плаваща запетая: една за географска ширина и втора за географска дължина. + +За всички класове реализирайте член-функция length, която връща размера на текстовото съобщение и operator<<. + +### Задача 9 + +Реализирайте абстрактен шаблонен клас MixedArray, който съхранява алтерниращи елементи от два типа, за тях имплементира голяма петица и задължава наследниците да имплементират оператори + и +=. +Елементите не е нужно да могат да се конвертират помежду си (тоест не може да използвате полиморфен контейнер). + +Реализирайте негов наследник DirectConcat, който реализира + и += като директно слепване (конкатениране). + +Реализирайте втори негов наследник, MixedConcat, който реализир + и += като алтернира елемент от първия масив с елемент от втория. + +## Трудни + +### Задача 10 + +Реализирайте система за документ с форматиран текст. +В нея всеки елемент от документа е от тип Node, като за един Node трябва да имате: + +- id, автоматично-избрано число, с което отличава Node +- operator<< +- operator[] + +Реализирайте следните типове Node: + +- paragraph, това е най-обикновен низ +- anchor, това е хипервръзка (линк), която съхранява видимо съдържание и уеб адрес +- emplaced link, това е хипервръзка при която видимото съдържание съвпада с уеб адреса +- заглавие, което е като хипервръзка, но уеб адресът започва с '#' и останалото съвпада със текстовото съдържание, като всяка буква е малка и вместо шпации има тирета +- bulletpoint list, който съхранява редица Node-ове и ги изкарва на екрана, всяко на нов ред, започващи с '-' +- table, която съхранява таблица с Node-ове + +Имплементирайте клас Document, който запазва масив от Node-ове и за който са имплементирани: + +- методи save и load, които запазват и четат цялото съдържание на документа в **текстов** файл с произволен формат. + +### Задача 11 + +Ще реализирате система за изпълнение на крайни автомати (от Теоретични Компютърни науки, ЕАИ). + +За тази цел е нужен абстрактен шаблонен клас State, чиито тип определя азбуката, който съхранява динамично-заделен масив от преходи (Transition) и задължава protected имплементация на член-функцията equal, която приема два елемента от азбуката и връща дали са равни. +Имплементирайте голяма петица и оператор +=, който вмъква нов преход в състоянието. + +Реализирайте абстрактен шаблонен клас Transition, чиито тип определя азбуката, и който съхранява елемент от този тип (стойността, която ако е равна на подадената ще изпълним прехода) и указател към следващо състояние. +Класът задължава имплементацията на оператор [], който по подаден елемент от азбуката или връща указателя към следващото състояние, или връща nullptr. + +Реализирайте наследник на State, ArrayState, който (допускате че) приема указател на динамичо-заделен масив. + +Реализирайте наследник на Transition, PrintedTransition, който при всяко извикване на оператор [] също изкарва съобщение на екрана. + +Реализирайте клас FiniteStateMachine, който съхранява динамичен масив от състояния. +За него имплементирайте голяма петица и конструктор, приемащ име на текстов файл в CSV формат, в който са запазени: + +- на първия ред обща информация във формата "Transitions,StartStateName", след това +- състояния и преходи във формата "StateName,OnValue,TransitionTo", после +- финални състояния във формата "FinalStateName1,FinalStateName2,...", и накрая +- входни букви от азбуката "Letter1,Letter2,...". + +Имплементирайте метод Run, който изпълнява автомата и връща булева стойност: дали приема входните букви или не. -- cgit v1.2.3