Website Summary Files Commits Branches @commit @diff @stats
path: root / Week05 / Exercise02
diff options
context:
space:
mode:
Commit571dc57f812a685bda7bd3baf8aaf2ef56feae65 (patch)
Author
 Syndamia <kamen@syndamia.com>
2026-03-28 16:19:58 +0200
Committer
 Syndamia <kamen@syndamia.com>
2026-03-28 16:19:58 +0200
Filesd69f560eccb705339f44be22369bb8fed025e642 /Week05/Exercise02
oop-2025-solutions-571dc57f812a685bda7bd3baf8aaf2ef56feae65.tar
oop-2025-solutions-571dc57f812a685bda7bd3baf8aaf2ef56feae65.tar.gz
oop-2025-solutions-571dc57f812a685bda7bd3baf8aaf2ef56feae65.zip
Parente5c06fbc864205a9736f07f9237ace80617ca471 (diff)
feat(Week05): Add solutions
4 files changed, 229 insertions, 0 deletions
-rw-r--r--Week05/Exercise02/String.cpp103
-rw-r--r--Week05/Exercise02/String.h32
-rw-r--r--Week05/Exercise02/Text.cpp67
-rw-r--r--Week05/Exercise02/Text.h27
diff --git a/Week05/Exercise02/String.cpp b/Week05/Exercise02/String.cpp
new file mode 100644
index 0000000..e2b082d
--- /dev/null
+++ b/Week05/Exercise02/String.cpp
@@ -0,0 +1,103 @@
+#include "String.h"
+#include <cstring>
+
+void String::free() {
+ delete[] str;
+}
+
+void String::copyFrom(const String& other) {
+ length = other.length;
+
+ // Не забравяме за терминиращата нула
+ str = new char[length + 1];
+ strncpy(str, other.str, length + 1);
+}
+
+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(const char* str) {
+ length = strlen(str);
+ this->str = new char[length + 1];
+ strncpy(this->str, str, length + 1);
+}
+
+String String::Substring(unsigned startIndex, unsigned length) const {
+ String result;
+ if (startIndex >= this->length) {
+ return result;
+ }
+
+ if (startIndex + length >= this->length) {
+ length = this->length - startIndex;
+ }
+
+ result.length = length;
+ result.str = new char[length + 1];
+ strncpy(result.str, str, length);
+ result.str[length + 1] = '\0';
+
+ return result;
+}
+
+void String::Concat(const String& end) {
+ char* newStr = new char[length + end.length + 1];
+ strncpy(newStr, str, length);
+ strncpy(newStr + length, end.str, end.length + 1);
+
+ delete[] str;
+ str = newStr;
+ length += end.length;
+}
+
+unsigned String::CountWords() const {
+ unsigned words = 0;
+ bool prevBlank = true;
+
+ for (const char* s = str; *s != '\0'; ++s) {
+ if (prevBlank && *s != ' ')
+ ++words;
+ prevBlank = *s == ' ';
+ }
+
+ return words;
+}
diff --git a/Week05/Exercise02/String.h b/Week05/Exercise02/String.h
new file mode 100644
index 0000000..f47b7c8
--- /dev/null
+++ b/Week05/Exercise02/String.h
@@ -0,0 +1,32 @@
+#ifndef _STRING
+#define _STRING
+
+class String {
+ char* str;
+ // Не е нужно да пазим и дължината като атрибут,
+ // можем винаги да си я смятаме с strlen, но
+ // е по-културно така
+ 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(const char* str);
+ String Substring(unsigned startIndex, unsigned length) const;
+ void Concat(const String& end);
+
+ /* Помощна функция */
+
+ unsigned CountWords() const;
+};
+
+#endif /* _STRING */
diff --git a/Week05/Exercise02/Text.cpp b/Week05/Exercise02/Text.cpp
new file mode 100644
index 0000000..b6143c0
--- /dev/null
+++ b/Week05/Exercise02/Text.cpp
@@ -0,0 +1,67 @@
+#include "Text.h"
+
+void Text::free() {
+ delete[] lines;
+}
+
+void Text::copyFrom(const Text& other) {
+ lineCount = other.lineCount;
+
+ lines = new String[lineCount];
+ for (unsigned i = 0; i < lineCount; ++i)
+ lines[i] = other.lines[i];
+}
+
+Text::Text() {
+ lines = nullptr;
+ lineCount = 0;
+}
+
+Text::~Text() {
+ free();
+}
+
+Text::Text(const Text& other) {
+ copyFrom(other);
+}
+
+Text& Text::operator=(const Text& other) {
+ if (this != &other) {
+ free();
+ copyFrom(other);
+ }
+ return *this;
+}
+
+Text::Text(Text&& other) {
+ lines = other.lines;
+ lineCount = other.lineCount;
+
+ other.lines = nullptr;
+ other.lineCount = 0;
+}
+
+unsigned Text::LineCount() const {
+ return lineCount;
+}
+
+unsigned Text::WordCount() const {
+ unsigned totalCount = 0;
+
+ for (unsigned i = 0; i < lineCount; ++i)
+ totalCount += lines[i].CountWords();
+
+ return totalCount;
+}
+
+Text Text::SubText(unsigned startLine, unsigned startCol, unsigned endLine, unsigned endCol) const {
+ Text result;
+ result.lineCount = endLine - startLine + 1;
+ result.lines = new String[lineCount];
+
+ for (unsigned i = 0; i < result.lineCount; ++i) {
+ result.lines[i] = lines[i + startLine].Substring(startCol, endCol - startCol + 1);
+ }
+
+ return result;
+}
diff --git a/Week05/Exercise02/Text.h b/Week05/Exercise02/Text.h
new file mode 100644
index 0000000..a1366e0
--- /dev/null
+++ b/Week05/Exercise02/Text.h
@@ -0,0 +1,27 @@
+#ifndef _TEXT
+#define _TEXT
+
+#include "String.h"
+
+class Text {
+ String* lines;
+ unsigned lineCount;
+
+ void free();
+ void copyFrom(const Text& other);
+
+public:
+ Text();
+ ~Text();
+ Text(const Text& other);
+ Text& operator=(const Text& other);
+
+ Text(Text&& other);
+ Text& operator=(Text&& other);
+
+ unsigned LineCount() const;
+ unsigned WordCount() const;
+ Text SubText(unsigned startLine, unsigned startCol, unsigned endLine, unsigned endCol) const;
+};
+
+#endif /* _TEXT */