Website Summary Files Commits Branches @commit @diff @stats
path: root / Week09 / Exercise05
diff options
context:
space:
mode:
Commitb38346eebca9a007971af02fb3bb9472c5e16d0c (patch)
Author
 Syndamia <kamen@syndamia.com>
2026-04-26 21:43:31 +0300
Committer
 Syndamia <kamen@syndamia.com>
2026-04-26 21:43:31 +0300
Files575a64089a17be271aec84683f426252d8f5d1f9 /Week09/Exercise05
oop-2025-solutions-b38346eebca9a007971af02fb3bb9472c5e16d0c.tar
oop-2025-solutions-b38346eebca9a007971af02fb3bb9472c5e16d0c.tar.gz
oop-2025-solutions-b38346eebca9a007971af02fb3bb9472c5e16d0c.zip
Parent7d98b664c9e459a08f2e6e6fa5b636686dfed554 (diff)
feat(Week09): Add solutions
5 files changed, 414 insertions, 0 deletions
-rw-r--r--Week09/Exercise05/String.cpp75
-rw-r--r--Week09/Exercise05/String.h28
-rw-r--r--Week09/Exercise05/StringArray.cpp219
-rw-r--r--Week09/Exercise05/StringArray.h80
-rw-r--r--Week09/Exercise05/main.cpp12
diff --git a/Week09/Exercise05/String.cpp b/Week09/Exercise05/String.cpp
new file mode 100644
index 0000000..903aa60
--- /dev/null
+++ b/Week09/Exercise05/String.cpp
@@ -0,0 +1,75 @@
+#include "String.h"
+#include <cstring>
+#include <iostream>
+
+void String::free() {
+ delete[] str;
+}
+
+void String::copyFrom(const String& other) {
+ length = other.length;
+ // Не забравяме за терминиращата нула
+ str = new char[length + 1];
+ strcpy(str, other.str);
+}
+
+String::String() {
+ str = nullptr;
+ length = 0;
+}
+
+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) {
+ str = other.str;
+ length = other.length;
+
+ other.str = nullptr;
+ other.length = 0;
+}
+
+String& String::operator=(String&& other) {
+ if (this != &other) {
+ free();
+
+ str = other.str;
+ length = other.length;
+
+ other.str = nullptr;
+ other.length = 0;
+ }
+ return *this;
+}
+
+String::String(unsigned length) {
+ this->length = length;
+ this->str = new char[length + 1];
+ this->str[length] = '\0';
+}
+
+void String::Copy(const char* str) {
+ if (this->str == nullptr) {
+ length = strlen(str);
+ this->str = new char[length + 1];
+ }
+ strncpy(this->str, str, length);
+ this->str[length] = '\0';
+}
+
+const char* String::GetStr() const {
+ return str;
+}
diff --git a/Week09/Exercise05/String.h b/Week09/Exercise05/String.h
new file mode 100644
index 0000000..08c7a79
--- /dev/null
+++ b/Week09/Exercise05/String.h
@@ -0,0 +1,28 @@
+#ifndef _STRING
+#define _STRING
+
+#include <ostream>
+
+class String {
+ char* str;
+ unsigned length;
+
+ 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);
+
+ String(unsigned length);
+ void Copy(const char* other);
+
+ const char* GetStr() const;
+};
+
+#endif /* _STRING */
diff --git a/Week09/Exercise05/StringArray.cpp b/Week09/Exercise05/StringArray.cpp
new file mode 100644
index 0000000..c3eca35
--- /dev/null
+++ b/Week09/Exercise05/StringArray.cpp
@@ -0,0 +1,219 @@
+#include "StringArray.h"
+#include <iostream>
+
+void StringArray::free() {
+ delete[] strings;
+}
+
+void StringArray::copyFrom(const StringArray& other) {
+ stringsCount = other.stringsCount;
+ stringsAlloc = other.stringsAlloc;
+ stringsAssigned = other.stringsAssigned;
+
+ strings = new String[stringsAlloc];
+ for (unsigned i = 0; i < stringsCount; ++i)
+ strings[i] = other.strings[i];
+}
+
+void StringArray::resize() {
+ stringsAlloc = stringsAlloc == 0 ? 8 : stringsAlloc * 2;
+ String* stringsLarger = new String[stringsAlloc];
+
+ for (unsigned i = 0; i < stringsCount; ++i)
+ stringsLarger[i] = strings[i];
+
+ delete[] strings;
+ strings = stringsLarger;
+}
+
+StringArray::StringArray() {
+ strings = nullptr;
+ stringsCount = stringsAlloc = stringsAssigned = 0;
+}
+
+StringArray::~StringArray() {
+ free();
+}
+
+StringArray::StringArray(const StringArray& other) {
+ copyFrom(other);
+}
+
+StringArray& StringArray::operator=(const StringArray& other) {
+ if (this != &other) {
+ free();
+ copyFrom(other);
+ }
+ return *this;
+}
+
+StringArray::StringArray(StringArray&& other) {
+ strings = other.strings;
+ stringsCount = other.stringsCount;
+ stringsAlloc = other.stringsAlloc;
+ stringsAssigned = other.stringsAssigned;
+
+ other.strings = nullptr;
+ other.stringsCount = other.stringsAlloc = other.stringsAssigned = 0;
+}
+
+StringArray& StringArray::operator=(StringArray&& other) {
+ if (this != &other) {
+ free();
+
+ strings = other.strings;
+ stringsCount = other.stringsCount;
+ stringsAlloc = other.stringsAlloc;
+ stringsAssigned = other.stringsAssigned;
+
+ other.strings = nullptr;
+ other.stringsCount = other.stringsAlloc = other.stringsAssigned = 0;
+ }
+ return *this;
+}
+
+void StringArray::PushLength(unsigned length) {
+ if (stringsCount >= stringsAlloc)
+ resize();
+ strings[stringsCount++] = String(length);
+}
+
+void StringArray::PushString(const char* str) {
+ if (stringsAssigned >= stringsAlloc)
+ resize();
+ strings[stringsAssigned++].Copy(str);
+
+ if (stringsAssigned > stringsCount)
+ stringsCount = stringsAssigned;
+}
+
+StringArray& StringArray::operator[](const Z& expectedNumbers) {
+ for (unsigned i = 0; i < expectedNumbers.numbersCount; ++i) {
+ PushLength(expectedNumbers.numbers[i]);
+ }
+ return *this;
+}
+
+StringArray& StringArray::operator()(const StringArray& strings) {
+ for (unsigned i = 0; i < strings.stringsAssigned; ++i) {
+ PushString(strings.strings[i].GetStr());
+ }
+ return *this;
+}
+
+StringArray& StringArray::operator()(const char* str) {
+ PushString(str);
+ return *this;
+}
+
+StringArray::StringArray(const char* str) : StringArray() {
+ PushString(str);
+}
+
+StringArray& StringArray::operator|(const char* str) {
+ PushString(str);
+ return *this;
+}
+
+// Това не е нужно по условие, но ще ни е
+// полезно за тестване.
+std::ostream& operator<<(std::ostream& ostr, const StringArray& sa) {
+ for (unsigned i = 0; i < sa.stringsAssigned; ++i)
+ ostr << sa.strings[i].GetStr() << std::endl;
+ return ostr;
+}
+
+/* Помощен клас Z */
+
+void Z::free() {
+ delete[] numbers;
+}
+
+void Z::copyFrom(const Z& other) {
+ numbersCount = other.numbersCount;
+ numbersAlloc = other.numbersAlloc;
+
+ numbers = new unsigned[numbersAlloc];
+ for (unsigned i = 0; i < numbersCount; ++i)
+ numbers[i] = other.numbers[i];
+}
+
+void Z::resize() {
+ numbersAlloc = numbersAlloc == 0 ? 8 : numbersAlloc * 2;
+ unsigned* numbersLarger = new unsigned[numbersAlloc];
+
+ for (unsigned i = 0; i < numbersCount; ++i)
+ numbersLarger[i] = numbers[i];
+
+ delete[] numbers;
+ numbers = numbersLarger;
+}
+
+Z::Z() {
+ numbers = nullptr;
+ numbersCount = numbersAlloc = 0;
+}
+
+Z::~Z() {
+ free();
+}
+
+Z::Z(const Z& other) {
+ copyFrom(other);
+}
+
+Z& Z::operator=(const Z& other) {
+ if (this != &other) {
+ free();
+ copyFrom(other);
+ }
+ return *this;
+}
+
+Z::Z(Z&& other) {
+ numbers = other.numbers;
+ numbersAlloc = other.numbersAlloc;
+ numbersCount = other.numbersCount;
+
+ other.numbers = nullptr;
+ other.numbersCount = other.numbersAlloc = 0;
+}
+
+Z& Z::operator=(Z&& other) {
+ if (this != &other) {
+ free();
+
+ numbers = other.numbers;
+ numbersAlloc = other.numbersAlloc;
+ numbersCount = other.numbersCount;
+
+ other.numbers = nullptr;
+ other.numbersCount = other.numbersAlloc = 0;
+ }
+ return *this;
+}
+
+Z::Z(unsigned number) {
+ numbersAlloc = 8;
+ numbersCount = 1;
+ numbers = new unsigned[numbersAlloc];
+ numbers[0] = number;
+}
+
+// Това е един метод да имплементираме operator++ и operator+,
+// където с ++ все едно подсказваме че ще добавяме елемент и с
+// + се добавя елемента.
+// Валидно е и ++ да не върши нищо и цялата логика да е в +.
+// Но така задължаваме употребата на "+++".
+
+Z& Z::operator++(int) {
+ if (numbersCount + 1 >= numbersAlloc)
+ resize();
+ return *this;
+}
+
+Z& Z::operator+(const Z& rhs) {
+ for (unsigned i = 0; i < rhs.numbersCount && numbersCount < numbersAlloc; ++i)
+ numbers[numbersCount++] = rhs.numbers[i];
+ return *this;
+}
diff --git a/Week09/Exercise05/StringArray.h b/Week09/Exercise05/StringArray.h
new file mode 100644
index 0000000..4b15ba0
--- /dev/null
+++ b/Week09/Exercise05/StringArray.h
@@ -0,0 +1,80 @@
+#ifndef _STRINGARRAY
+#define _STRINGARRAY
+
+#include "String.h"
+#include <ostream>
+
+// Декларация на класа, за да може в StringArray
+// да си го използваме преди пълната дефиниция
+class Z;
+
+class StringArray {
+ String* strings;
+ unsigned stringsCount;
+ unsigned stringsAlloc;
+
+ unsigned stringsAssigned;
+
+ void free();
+ void copyFrom(const StringArray& other);
+ void resize();
+
+public:
+ StringArray();
+ ~StringArray();
+ StringArray(const StringArray& other);
+ StringArray& operator=(const StringArray& other);
+
+ StringArray(StringArray&& other);
+ StringArray& operator=(StringArray&& other);
+
+ void PushLength(unsigned length);
+ void PushString(const char* str);
+
+ StringArray& operator[](const Z& expectedNumbers);
+
+ // Можем да създадем помощен клас "PassedStrings".
+ // Обаче нямаме ограничение което задължава StringArray и
+ // PassedStrings да са различни класове.
+ // Можем и просто да се възползваме от StringArray,
+ // и да си спестим писане на код.
+ StringArray& operator()(const StringArray& strings);
+ StringArray& operator()(const char* str);
+ StringArray(const char* str);
+
+ // Оператор "|" е ляво асоциативен
+ StringArray& operator|(const char* str);
+
+ // Това не е нужно по условие, но ще ни е
+ // полезно за тестване.
+ friend std::ostream& operator<<(std::ostream& ostr, const StringArray& sa);
+};
+
+class Z {
+ unsigned* numbers;
+ unsigned numbersCount;
+ unsigned numbersAlloc;
+
+ void free();
+ void copyFrom(const Z& other);
+ void resize();
+
+public:
+ Z();
+ ~Z();
+ Z(const Z& other);
+ Z& operator=(const Z& other);
+
+ Z(Z&& other);
+ Z& operator=(Z&& other);
+
+ Z(unsigned num);
+
+ Z& operator++(int);
+ Z& operator+(const Z& rhs);
+
+ friend StringArray;
+};
+
+
+#endif /* _STRINGARRAY */
diff --git a/Week09/Exercise05/main.cpp b/Week09/Exercise05/main.cpp
new file mode 100644
index 0000000..8bf6a6c
--- /dev/null
+++ b/Week09/Exercise05/main.cpp
@@ -0,0 +1,12 @@
+#include "StringArray.h"
+#include <iostream>
+
+int main() {
+ StringArray s;
+
+ // Защо за числата трябва да конвертираме всички, а при | конвертираме само първия?
+ s[ Z(7) +++ Z(4) +++ Z(3) ] ("") (StringArray("Hello")|"World") [ Z(4) +++ Z(5) +++ Z(1) ] ("!") [ Z(2) ] (StringArray("Code")|"A"|"B");
+
+ std::cout << s;
+ return 0;
+}