Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "book.hh"
- #include <algorithm>
- using namespace std;
- Book::Book() {
- }
- Book::~Book(){
- }
- void Book::addNewChapter(const std::string &id,
- const std::string &fullName, int length) {
- shared_ptr<Chapter> chapter {new Chapter};
- chapter -> id_ = id;
- chapter -> fullName_ = fullName;
- chapter -> length_ = length;
- chapter -> running_id_ = running_id;
- running_id++;
- // try insert for a change instad of map::operator[]
- idstore.insert(pair<string, shared_ptr<Chapter>>(id, chapter));
- }
- void Book::addRelation(const std::string &subchapter,
- const std::string &parentChapter) {
- if (parentChapter.length() > 0) {
- shared_ptr<Chapter> s_ch = findChapter(subchapter);
- shared_ptr<Chapter> p_ch = findChapter(parentChapter);
- p_ch-> subchapters_.push_back(s_ch);
- s_ch -> parentChapter_ = p_ch;
- }
- }
- void Book::printIds(Params) const {
- cout << "Book has " << idstore.size() << " chapters:" << endl;
- vector <string> to_sort;
- for (auto& [id, chapter] : idstore) {
- to_sort.push_back(chapter->fullName_ + " --- " + id);
- }
- // sort vector to ascii order
- std::sort (to_sort.begin(), to_sort.end(), compare);
- for (auto& chapter : to_sort) {
- cout << chapter << endl;
- }
- }
- void Book::printContents(Params) const {
- // get a list of top chapters
- // map sorts running id's automatically to asc order
- std::map<int, std::string> top_chapters;
- for (auto& [id, chapter] : idstore) {
- if (chapter->parentChapter_ == nullptr) {
- top_chapters.insert(
- pair<int, std::string> (chapter->running_id_,
- chapter->id_));
- }
- }
- // iterate through top chapters, printing them and their subchapters
- int i = 1;
- for (auto& val : top_chapters) {
- // avoid typing idstore.at(val.second) repeatedly
- auto& chapter = idstore.at(val.second);
- // is chapter open or closed?
- string status = chapter->isopen_ ? "- " : "+ ";
- // print chapter details
- cout << status << i << ". " << chapter->fullName_
- << " ( " << chapter->length_ << " )" << endl;
- i++;
- // recursively call func again if chapter has subchapters
- if(chapter->subchapters_.size() > 0 and chapter->isopen_) {
- print_subchapters(chapter->id_, 2);
- }
- }
- }
- // Recursively closes all chapters and subchapters
- // starting from the given chapter.
- void Book::close(Params params) const
- {
- string to_close = params.front();
- // check if chapter exists
- shared_ptr<Chapter> chapter = findChapter(to_close);
- if(chapter == nullptr) { return; }
- // close chapter if open
- if (chapter->isopen_)
- {
- chapter->isopen_ = false;
- // if subchapters exist, check if they need closing too
- if (chapter->subchapters_.size() > 0) {
- for (auto& val : chapter->subchapters_) {
- close(vector<string> {val->id_});
- }
- }
- }
- }
- void Book::open(Params params) const {
- string to_open = params.front();
- // check if chapter exists
- shared_ptr<Chapter> chapter = findChapter(to_open);
- if(chapter == nullptr) { return; }
- chapter->isopen_ = true;
- // open subchapters if they don't have subchapters
- if (chapter->subchapters_.size() > 0) {
- for (auto& val : chapter->subchapters_) {
- if (val->subchapters_.size() == 0 )
- val->isopen_ = true;
- }
- }
- }
- void Book::openAll(Params) const {
- for (auto& [id, chapter] : idstore) {
- chapter->isopen_ = true;
- }
- }
- void Book::printParentsN(Params params) const {
- string id = params.at(0);
- int level = stoi(params.at(1));
- // level must be at least 1.
- if (level < 1) {
- cout << "Error. Level can't be less than 1." << endl;
- return;
- }
- shared_ptr<Chapter> chapter = findChapter(id);
- // no chapter?
- if (chapter == nullptr) { return; }
- // no parent chapter?
- if (chapter->parentChapter_ == nullptr) {
- cout << id << " has no parent chapters." << endl;
- return;
- }
- // else print subchapters to depth n
- auto list = make_shared<vector<string>>();
- get_parents(list, chapter, 0, level);
- // sort to ASCII order
- std::sort (list->begin(), list->end(), compare);
- cout << id << " has " << list->size() << " parent chapters:" << endl;
- for (auto& val : *list) {
- cout << val << endl;
- }
- }
- void Book::printSubchaptersN(Params params) const {
- string id = params.at(0);
- int max_depth = stoi(params.at(1));
- // level must be at least 1.
- if (max_depth < 1) {
- cout << "Error. Level can't be less than 1." << endl;
- return;
- }
- shared_ptr<Chapter> chapter = findChapter(id);
- // no chapter?
- if (chapter == nullptr) { return; }
- // no subchapters?
- if (chapter->subchapters_.size() == 0) {
- cout << id << " has no subchapters." << endl;
- return;
- }
- // else print subchapters to depth n
- auto list = make_shared<vector<string>>();
- get_subchapters(list, id, 0, max_depth);
- // sort to ASCII order
- std::sort (list->begin(), list->end(), compare);
- cout << id << " has " << list->size() << " subchapters:" << endl;
- for (auto& val : *list) {
- cout << val << endl;
- }
- }
- void Book::printSiblingChapters(Params params) const {
- string id = params.at(0);
- shared_ptr<Chapter> chapter = findChapter(id);
- // no chapter?
- if (chapter == nullptr) { return; }
- // top tier chapters have no siblings
- if (chapter->parentChapter_ == nullptr) {
- cout << id << " has no sibling chapters." << endl;
- return;
- }
- // info msg about findings
- cout << id << " has " << chapter->parentChapter_->subchapters_.size() - 1
- << " sibling chapters:" << endl;
- // get parent chapter and print its subchapters except id
- for (auto& val : chapter->parentChapter_->subchapters_) {
- if (val->id_ != id) {
- cout << val-> id_ << endl;
- }
- }
- }
- void Book::printTotalLength(Params params) const{
- string id = params.at(0);
- shared_ptr<Chapter> chapter = findChapter(id);
- // no chapter?
- if (chapter == nullptr) { return; }
- int length = 0;
- // add provided chapter to length
- length += idstore.at(id)->length_;
- // get subchapters to depth n
- // TODO get_subchapters to work with inf depth
- auto list = make_shared<vector<string>>();
- get_subchapters(list, id, 0, 9999);
- // add subchapters to length
- for (auto& val : *list) {
- length += idstore.at(val)->length_;
- }
- cout << "Total length of " << id << " is " << length << "." << endl;
- }
- void Book::printLongestInHierarchy(Params params) const {
- string id = params.at(0);
- string longest_id = id;
- // intialize provided chapter as longest
- shared_ptr<Chapter> chapter = findChapter(id);
- // no chapter?
- if (chapter == nullptr) { return; }
- int longest_len = chapter->length_;
- // get subchapters to depth n
- // TODO get_subchapters to work with inf depth
- auto list = make_shared<vector<string>>();
- get_subchapters(list, id, 0, 9999);
- for (auto& val : *list) {
- if (idstore.at(val)->length_ > longest_len) {
- longest_len = idstore.at(val)->length_;
- longest_id = val;
- }
- }
- // print result
- cout << "With the length of " << longest_len << ", "
- << longest_id << " is the longest chapter in ";
- if (longest_id == id) {
- cout << "their ";
- } else {
- cout << id << "'s ";
- }
- cout << "hierarchy." << endl;
- }
- void Book::printShortestInHierarchy(Params params) const {
- string id = params.at(0);
- string shortest_id = id;
- // intialize provided chapter as longest
- shared_ptr<Chapter> chapter = findChapter(id);
- // no chapter?
- if (chapter == nullptr) { return; }
- int shortest_len = chapter->length_;
- // get subchapters to depth n
- // TODO get_subchapters to work with inf depth
- auto list = make_shared<vector<string>>();
- get_subchapters(list, id, 0, 9999);
- for (auto& val : *list) {
- if (idstore.at(val)->length_ < shortest_len) {
- shortest_len = idstore.at(val)->length_;
- shortest_id = val;
- }
- }
- // print result
- cout << "With the length of " << shortest_len << ", "
- << shortest_id << " is the shortest chapter in ";
- if (shortest_id == id) {
- cout << "their ";
- } else {
- cout << id << "'s ";
- }
- cout << "hierarchy." << endl;
- }
- std::shared_ptr<Chapter> Book::findChapter(const std::string &id) const {
- auto iter = idstore.find(id);
- if (iter != idstore.end()) {
- return iter->second;
- }
- cout << "Error: Not found: " << id << endl;
- return nullptr;
- }
- void Book::print_subchapters(std::string id, int padding) const
- {
- int i = 1;
- for (auto& val : idstore.at(id)->subchapters_) {
- // is chapter open or closed?
- string status = val->isopen_ ? "- " : "+ ";
- cout << status;
- // string() prints padding n times without a loop
- cout << string(padding, ' ');
- // print chapter details
- cout << i << ". " << val->fullName_
- << " ( " << val->length_ << " )" << endl;
- i++;
- // recursively call func again if chapter has subchapters
- if (val->subchapters_.size() > 0 and val->isopen_) {
- print_subchapters(val->id_, padding+2);
- }
- }
- return;
- }
- void Book::get_subchapters(shared_ptr<vector<string>> list,
- string id,
- int cur_depth,
- int max_depth) const
- {
- cur_depth++;
- // look for subchapters at current depth
- shared_ptr<Chapter> chapter = findChapter(id);
- for (auto& val : chapter->subchapters_) {
- list->push_back(val->id_);
- // go deeper if needed
- if (cur_depth < max_depth) {
- get_subchapters(list, val->id_, cur_depth, max_depth);
- }
- }
- }
- void Book::get_parents(shared_ptr<vector<string>> list,
- std::shared_ptr<Chapter> chapter,
- int cur_level,
- int max_level) const
- {
- // add current level's parent if one exists
- if (chapter->parentChapter_ != nullptr) {
- list->push_back(chapter->parentChapter_->id_);
- cur_level++;
- // go higher if needed
- if (cur_level < max_level) {
- get_parents(list, chapter->parentChapter_, cur_level, max_level);
- }
- }
- }
- bool Book::compare(std::string& a, std::string& b) {
- if (a < b) {
- return true;
- }
- return false;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement