// // example of using recursive linked-list class: // // define and illustrate use of "shopping list" class. // // version 2 // // changes from version 1: // use "typedef". // print items in same order added. // make sure items are unique. // add replaceItem() function. // change main program to interactive test. // #include #include // has EXIT_SUCCESS #include #include "seq.h" // has Seq template class // // "shopping list" class // class ShopList { private: typedef Seq slist; // shorthand for Seq public: // public interface for class: // constructor. // post: constructed ShopList has no items. ShopList() { items = slist(); } // function to print items. // post: all items in list printed to stdout, in // order in which they were added. void printItems() const { print(items); } // function to search for item. // post: returns true if itm is in list, false otherwise. bool hasItem(const string & itm) const { return has(itm, items); } // function to add item. // pre: items in list are unique. // post: "itm" added to list at "end" if not already present. // note that items in list are still unique. void addItem(const string & itm) { if (!hasItem(itm)) items = slist(itm, items); } // function to remove item. // pre: items in list are unique. // post: "itm" removed from list if present. note that items // in list are still unique. void removeItem(const string & itm) { items = remove(itm, items); } // function to replace item. // pre: items in list are unique. // post: if "newItm" already in list, "oldItm" removed; // otherwise "oldItm" replaced by "newItm" if in list. // note that items in list are still unique. void replaceItem(const string & oldItm, const string & newItm) { if (hasItem(newItm)) removeItem(oldItm); else items = replace(oldItm, newItm, items); } private: // list of items, in reverse order of addition. slist items; // helper functions: // function to print list of strings. // post: l printed to stdout, in reverse order. static void print(const slist & l) { if (l.empty()) return; else { print(l.tl()); cout << l.hd() << endl; } } // function to find item in list of strings. // post: returns true if itm is in l, false otherwise. static bool has(const string & itm, const slist & l) { if (l.empty()) return false; else return (l.hd() == itm) || has(itm, l.tl()); } // function to remove item from list of strings. // pre: items in l are unique. // post: returns l' = l with itm removed. note that items in // l' are unique. static slist remove(const string & itm, const slist & l) { if (l.empty()) return l; else if (l.hd() == itm) return l.tl(); else return slist(l.hd(), remove(itm, l.tl())); } // function to replace item in list of strings. // pre: items in l are unique, newItm is not already in l. // post: returns l' = l with oldItm replaced by newItm if present. static slist replace(const string & oldItm, const string & newItm, const slist & l) { if (l.empty()) return l; else if (l.hd() == oldItm) return slist(newItm, l.tl()); else return slist(l.hd(), replace(oldItm, newItm, l.tl())); } }; // // main program: // // allows interactive testing of ShopList class functions. // int main(void) { ShopList myList; char command; string t1; string t2; char prompt[] = "What do you want to do?\n" " a to add item\n" " d to remove item\n" " r to replace item\n" " q to quit\n" "Your choice? "; cout << "Current list:\n"; myList.printItems(); cout << prompt; while ((cin >> command) && (command != 'q')) { cin.ignore(10000, '\n'); // discard EOF so we can use getline if (command == 'a') { cout << "Item to add? "; getline(cin, t1); myList.addItem(t1); } else if (command == 'd') { cout << "Item to remove? "; getline(cin, t1); myList.removeItem(t1); } else if (command == 'r') { cout << "Item to replace? "; getline(cin, t1); cout << "Item to replace it with? "; getline(cin, t2); myList.replaceItem(t1, t2); } else cout << "Unrecognized command.\n"; cout << "Current list:\n"; myList.printItems(); cout << prompt; } return EXIT_SUCCESS; }