#include "WordCollection.h" #include "cstring" #include /* Private */ void WordCollection::free() { if(words != nullptr) delete[] words; if(sortMap != nullptr) delete[] sortMap; } void WordCollection::copyFrom(const WordCollection& other) { count = other.count; length = other.length; words = new DynStr[length]; sortMap = new int[length]; for (int i = 0; i < count; i++) { words[i] = other.words[i]; sortMap[i] = other.sortMap[i]; } } void WordCollection::resize() { if (length == 0) length = 8; else length <<= 1; DynStr* newWords = new DynStr[length]; int* newSortMap = new int[length]; for (int i = 0; i < count; i++) { newWords[i] = words[i]; newSortMap[i] = sortMap[i]; } if (words != nullptr) delete[] words; if (sortMap != nullptr) delete[] sortMap; words = newWords; sortMap = newSortMap; } void WordCollection::insertSortMapIndex(int position, int value) { if (position == -1) position = count; for (int i = count; i > position; i--) sortMap[i] = sortMap[i - 1]; sortMap[position] = value; } void WordCollection::removeSortMapIndex(int position) { for (int i = position; i <= count - 2; i++) sortMap[i] = sortMap[i + 1]; sortMap[count - 1] = 0; } int WordCollection::findSortMapIndexWhen(int condition, const char* str) { if (condition < -1) condition = -1; else if (condition > 1) condition = 1; // TODO: replace with binary search for (int i = 0; i < count; i++) { int cmp = strcmp(words[sortMap[i]].get_str(), str); if (cmp > 1) cmp = 1; else if (cmp < -1) cmp = -1; if (cmp == condition) return i; } return -1; } /* Public */ WordCollection::WordCollection() { words = nullptr; sortMap = nullptr; count = length = 0; } WordCollection::WordCollection(const WordCollection& other) { copyFrom(other); } WordCollection& WordCollection::operator=(const WordCollection& other) { if (this != &other) { free(); copyFrom(other); } return *this; } WordCollection::~WordCollection() { free(); } WordCollection& WordCollection::operator+=(const WordCollection& other) { for (int i = 0; i < other.count; i++) { (*this) *= other.words[i].get_str(); } return *this; } WordCollection& WordCollection::operator-=(const WordCollection& other) { for (int i = 0; i < other.count; i++) { (*this) /= other.words[i].get_str(); } return *this; } WordCollection& WordCollection::operator*=(const char* str) { if (!(*this)[str]) { if (count == length) resize(); words[count] = DynStr(str); insertSortMapIndex(findSortMapIndexWhen(1, str), count); count++; } return *this; } WordCollection& WordCollection::operator/=(const char* str) { int ind = findSortMapIndexWhen(0, str); if (ind > -1) { words[sortMap[ind]] = DynStr(); removeSortMapIndex(ind); count--; } return *this; } std::ostream& operator<<(std::ostream& ostrm, const WordCollection& collection) { ostrm << "{"; for (int i = 0; i <= collection.count - 2; i++) ostrm << collection.words[collection.sortMap[i]].get_str() << ", "; ostrm << collection.words[collection.sortMap[collection.count - 1]].get_str() << "}"; return ostrm; } std::istream& operator>>(std::istream& istrm, WordCollection& collection) { char buffer[1024]; istrm.getline(buffer, 1024); collection *= buffer; return istrm; } bool WordCollection::operator[](const char* str) { return findSortMapIndexWhen(0, str) > -1; } const WordCollection operator+(const WordCollection& lhs, const WordCollection& rhs) { WordCollection res(lhs); res += rhs; return res; } const WordCollection operator-(const WordCollection& lhs, const WordCollection& rhs) { WordCollection res(lhs); res -= rhs; return res; }