diff options
feat(Week09): Add solutions
3 files changed, 229 insertions, 0 deletions
| -rw-r--r-- | Week09/Exercise03/String.cpp | 153 | ||||
| -rw-r--r-- | Week09/Exercise03/String.h | 61 | ||||
| -rw-r--r-- | Week09/Exercise03/main.cpp | 15 |
diff --git a/Week09/Exercise03/String.cpp b/Week09/Exercise03/String.cpp new file mode 100644 index 0000000..a0b2565 --- /dev/null +++ b/Week09/Exercise03/String.cpp @@ -0,0 +1,153 @@ +#include "String.h" +#include <cstring> + +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; + + str = nullptr; + length = 0; + } + return *this; +} + +String::String(const char* str) { + this->length = strlen(str); + this->str = new char[this->length + 1]; + strcpy(this->str, str); +} + +std::ostream& operator<<(std::ostream& ostr, const String& string) { + if (string.str == nullptr) + return ostr << ""; + return ostr << string.str; +} + +String& String::operator+=(const String& other) { + char* largerStr = new char[length + other.length + 1]; + strcpy(largerStr, str); + strcat(largerStr, other.str); + + delete[] str; + str = largerStr; + length += other.length; + + return *this; +} + +char String::operator[](unsigned index) const { + return str[index]; +} + +String::IndexRange::IndexRange(unsigned index) { + start = end = index; +} + +String::IndexRange& String::IndexRange::operator,(const IndexRange& rhs) { + if (rhs.start < this->start) + this->start = rhs.start; + if (this->end < rhs.end) + this->end = rhs.end; + return *this; +} + +String String::operator[](IndexRange range) const { + if (range.end >= length) + range.end = length - 1; + if (range.start > range.end) + return String(); + if (range.start == 0 && range.end == length - 1) + return *this; + + String substr; + substr.length = range.end - range.start + 1; + substr.str = new char[substr.length + 1]; + + strncpy(substr.str, str + range.start, substr.length); + substr.str[substr.length] = '\0'; + + return substr; +} + +bool operator==(const String& lhs, const String& rhs) { + return strcmp(lhs.str, rhs.str) == 0; +} + +bool operator!=(const String& lhs, const String& rhs) { + return !(lhs == rhs); +} + +bool operator<(const String& lhs, const String& rhs) { + return strcmp(lhs.str, rhs.str) < 0; +} + +bool operator<=(const String& lhs, const String& rhs) { + return strcmp(lhs.str, rhs.str) <= 0; +} + +bool operator>(const String& lhs, const String& rhs) { + return strcmp(lhs.str, rhs.str) > 0; +} + +bool operator>=(const String& lhs, const String& rhs) { + return strcmp(lhs.str, rhs.str) >= 0; +} + +bool operator<<(const String& lhs, const String& rhs) { + if (rhs.length > lhs.length) + return false; + return strcmp(lhs.str + (lhs.length - rhs.length), rhs.str) == 0; +} + +bool operator>>(const String& lhs, const String& rhs) { + if (lhs.length > rhs.length) + return false; + return strncmp(lhs.str, rhs.str, lhs.length) == 0; +} + +String operator+(const String& lhs, const String& rhs) { + return String(lhs) += rhs; +} diff --git a/Week09/Exercise03/String.h b/Week09/Exercise03/String.h new file mode 100644 index 0000000..674813c --- /dev/null +++ b/Week09/Exercise03/String.h @@ -0,0 +1,61 @@ +#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 + String(const char* str); + friend std::ostream& operator<<(std::ostream& ostr, const String& string); + + // Каза ни са кои оператори трябва да бъдат имплементирани, + // но както помощни функции, можем да си имплементираме и други + // оператори + String& operator+=(const String& other); + + char operator[](unsigned index) const; + + const char* te() const { + return str; + } + + struct IndexRange { + unsigned start; + unsigned end; + + IndexRange(unsigned index); + IndexRange& operator,(const IndexRange& rhs); + }; + String operator[](IndexRange range) const; + + // Алтернативно, може да създадем селектори + // GetStr който връща str указателя и GetLength, + // и тези функции няма да е нужно да са приятелски + friend bool operator==(const String& lhs, const String& rhs); + friend bool operator!=(const String& lhs, const String& rhs); + friend bool operator<(const String& lhs, const String& rhs); + friend bool operator<=(const String& lhs, const String& rhs); + friend bool operator>(const String& lhs, const String& rhs); + friend bool operator>=(const String& lhs, const String& rhs); + friend bool operator<<(const String& lhs, const String& rhs); + friend bool operator>>(const String& lhs, const String& rhs); +}; + +String operator+(const String& lhs, const String& rhs); + +#endif /* _STRING */ diff --git a/Week09/Exercise03/main.cpp b/Week09/Exercise03/main.cpp new file mode 100644 index 0000000..087b05f --- /dev/null +++ b/Week09/Exercise03/main.cpp @@ -0,0 +1,15 @@ +#include "String.h" +#include <iostream> + +int main() { + String a = "Hello"; + String b = "World"; + + String c = a + " " + b; + + std::cout << c << std::endl; + std::cout << (c << b) << ' ' << (a >> c) << std::endl; + std::cout << c[String::IndexRange(2), 7] << std::endl; + + return 0; +} |
