DragonOsman

linked_lists.cpp

Oct 1st, 2017
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.67 KB | None | 0 0
  1. // Osman Zakir
  2. // 9 / 7 / 2017
  3. // Bjarne Stroustrup: Programming: Principles and Practice Using C++ 2nd Edition
  4. // Chapter 17 Exercises 11-13
  5.  
  6. #include <cctype>
  7. #include <iostream>
  8. #include <iterator>
  9. #include <algorithm>
  10. #include "../../cust_std_lib_facilities.h"
  11.  
  12. struct God
  13. {
  14.     God(const std::string &name, const std::string &myth, const std::string &vehicle, const std::string &weapon)
  15.         : m_name{ name }, m_myth{ myth }, m_vehicle{ vehicle }, m_weapon{ weapon } { }
  16.  
  17.     const std::string &name() const { return m_name; }
  18.     const std::string &myth() const { return m_myth; }
  19.     const std::string &vehicle() const { return m_vehicle; }
  20.     const std::string &weapon() const { return m_weapon; }
  21.  
  22.     void set_name(const std::string name) { m_name = name; }
  23.     void set_myth(const std::string myth) { m_myth = myth; }
  24.     void set_vehicle(const std::string vehicle) { m_vehicle = vehicle; }
  25.     void set_weapon(const std::string weapon) { m_weapon = weapon; }
  26. private:
  27.     std::string m_name;
  28.     std::string m_myth;
  29.     std::string m_vehicle;
  30.     std::string m_weapon;
  31. };
  32.  
  33. class Link
  34. {
  35. public:
  36.     Link(const God &god, Link *p = nullptr, Link *s = nullptr)
  37.         : m_god{ god }, m_prev{ p }, m_succ{ s } { }
  38.  
  39.     God m_god;
  40.     Link *insert(Link *n);                              // insert n before this object
  41.     Link *add(Link *n);                                 // insert n after this object
  42.     Link *erase();                                      // remove this object from list
  43.     Link *find(const std::string &name);                // find values in list
  44.     const Link *find(const std::string &name) const;    // find values in const list
  45.     Link *advance(int n) const;                         // advance n positions in list
  46.     Link *add_ordered(Link *n);
  47.     int element_count();
  48.  
  49.     Link *next() const { return m_succ; }
  50.     Link *previous() const { return m_prev; }
  51.  
  52. private:
  53.     Link *m_prev;
  54.     Link *m_succ;
  55. };
  56.  
  57. void print_all(Link *p);
  58. bool no_case(char a, char b);
  59.  
  60. int main()
  61. {
  62.     Link *norse_gods = new Link{ God{ "Thor", "Norse",
  63.         "Chariot pulled by goats Tanngrisnir and Tanngnjostr", "Mjolnir" } };
  64.     norse_gods = norse_gods->add_ordered(new Link{ God{ "Odin", "Norse",
  65.         "Eight-legged flying horse called Sleipnir", "Spear called Gungnir" } });
  66.     norse_gods = norse_gods->add_ordered(new Link{ God{ "Zeus", "Greek", "", "Lightning" } });
  67.  
  68.     print_all(norse_gods);
  69.     std::cout << '\n';
  70.  
  71.     keep_window_open();
  72. }
  73.  
  74. Link *Link::insert(Link *n)
  75. {
  76.     if (n == nullptr)
  77.     {
  78.         return this;
  79.     }
  80.     n->m_succ = this;
  81.     if (m_prev)
  82.     {
  83.         m_prev->m_succ = n;
  84.     }
  85.     n->m_prev = m_prev;
  86.     m_prev = n;
  87.     return n;
  88. }
  89.  
  90. Link *Link::add(Link *n)
  91. {
  92.     if (n == nullptr)
  93.     {
  94.         return this;
  95.     }
  96.     n->m_prev = this;
  97.     if (m_succ)
  98.     {
  99.         m_succ->m_prev = n;
  100.     }
  101.     n->m_succ = m_succ;
  102.     m_succ = n;
  103.     return n;
  104. }
  105.  
  106. Link *Link::erase()
  107. {
  108.     Link *trav = this;
  109.     if (trav == nullptr)
  110.     {
  111.         return nullptr;
  112.     }
  113.     if (trav->m_succ)
  114.     {
  115. trav->m_succ->m_prev = trav->m_prev;
  116.     }
  117.     if (trav->m_prev)
  118.     {
  119.         trav->m_prev->m_succ = trav->m_succ;
  120.     }
  121.     return trav->m_succ;
  122. }
  123.  
  124. Link *Link::find(const std::string &name)
  125. {
  126.     Link *trav = this;
  127.     while (trav != nullptr)
  128.     {
  129.         if (trav->m_god.name() == name)
  130.         {
  131.             return trav;
  132.         }
  133.         trav = trav->m_succ;
  134.     }
  135.     return nullptr;
  136. }
  137.  
  138. const Link *Link::find(const std::string &name) const
  139. {
  140.     const Link *c_trav = this;                    // const pointer
  141.     Link *nc_trav = const_cast<Link*>(c_trav);    // non-const pointer
  142.     while (c_trav != nullptr && nc_trav != nullptr)
  143.     {
  144.         if (c_trav->m_god.name() == name)
  145.         {
  146.             return c_trav;
  147.         }
  148.         nc_trav = nc_trav->m_succ;
  149.     }
  150.     return nullptr;
  151. }
  152.  
  153. Link *Link::advance(int n) const
  154. {
  155.     Link *trav = const_cast<Link *>(this);
  156.     if (trav == nullptr)
  157.     {
  158.         return nullptr;
  159.     }
  160.     if (n > 0)
  161.     {
  162.         while (n--)
  163.         {
  164.             if (trav->m_succ == nullptr)
  165.             {
  166.                 return nullptr;
  167.             }
  168.             trav = trav->m_succ;
  169.         }
  170.     }
  171.     else if (n < 0)
  172.     {
  173.         while (n++)
  174.         {
  175.             if (trav->m_prev == nullptr)
  176.             {
  177.                 return nullptr;
  178.             }
  179.             trav = trav->m_prev;
  180.         }
  181.     }
  182.     return trav;
  183. }
  184.  
  185. /**
  186.  * This function is for use in lexicographical_compare() as a custom compare,
  187.  * such that the function does a case-insensitive compare of the two strings
  188.  */
  189. bool no_case(char a, char b)
  190. {
  191.     return tolower(a) < tolower(b);
  192. }
  193.  
  194. /**
  195.  * This function's specs are as follows:
  196.  * Add a member function add_ordered() that places its new element in its correct lexicographical position.
  197.  * Using the Links with the values of type God, make a list of gods from three mythologies; then move the
  198.  * elements (gods) from that list to three lexicographically ordered lists — one for each mythology.
  199.  */
  200. Link *Link::add_ordered(Link *n)
  201. {
  202.     if (n == nullptr)
  203.     {
  204.         return nullptr;
  205.     }
  206.  
  207.     Link *trav = this;
  208.     if (trav == nullptr)
  209.     {
  210.         return nullptr;
  211.     }
  212.  
  213.     std::string key = n->m_god.name();
  214.     while (trav->m_succ)
  215.     {
  216.         if (std::lexicographical_compare(key.begin(), key.end(), trav->m_god.name().begin(), trav->m_god.name().end(), no_case))
  217.         {
  218.             trav = trav->insert(n);
  219.         }
  220.         else
  221.         {
  222.             trav = trav->add(n);
  223.         }
  224.         trav = trav->m_succ;
  225.     }
  226.     return trav;
  227. }
  228.  
  229. int Link::element_count()
  230. {
  231.     Link *trav = this;
  232.     int size = 0;
  233.     if (trav)
  234.     {
  235.         while (trav->m_succ)
  236.         {
  237.             size++;
  238.             trav = trav->m_succ;
  239.         }
  240.     }
  241.     return size + 1;
  242. }
  243.  
  244. void print_all(Link *p)
  245. {
  246.     std::cout << "{\n";
  247.     while (p)
  248.     {
  249.         std::cout << "Name: " << p->m_god.name() << '\n'
  250.             << "Myth: " << p->m_god.myth() << '\n';
  251.         if (p->m_god.vehicle() != "")
  252.         {
  253.             std::cout << "Vehicle: " << p->m_god.vehicle() << '\n';
  254.         }
  255.         else
  256.         {
  257.             std::cout << "Vehicle: N/A\n";
  258.         }
  259.         std::cout << "Weapon: " << p->m_god.weapon() << '\n';
  260.         if ((p = p->next()))
  261.         {
  262.             std::cout << "\n";
  263.         }
  264.     }
  265.     std::cout << "}";
  266. }
Add Comment
Please, Sign In to add comment