doubly linked lists


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 7 of 7

Thread: doubly linked lists

  1. #1
    Join Date
    Oct 2017
    Posts
    1

    doubly linked lists

    hello,

    while studying for our short tests, our tutor gave us this problem to complete telling us that if we could do this it would be great. problem is we havnt quiet covered the syllabus yet and yet its coming in the papers and we are xpected to learn on our own.

    with a partially completed projet, we are supposed to finish it where by the user enters a country name, its region, economy, tourist arrivals, tourism rankings. together with this we are supposed to enter the name of the cities and state whether it is the capital city or not, the tourist arrival of the particular city, and if u can travel there by air.

    i've done a lil bit but im really stuck.

    find attached a document outlining the major implementations to be done and a graphical view of the linked lists. bt im truely confused til now. i cant seem to enter the data. templetes are used also.

    can some1 please tel me what and how to do pliz?

    here's what i've done so far. the main program and the country class implementation has to be completed. also in country class, this piece of code NODE<city> * _city, what do i have to do with this?

    thanks


    Code:
    #include <iostream.h>
    #include <stdlib.h>
    #include <string>
    using namespace std;
    
    
    //------------------------------------------------------------------------
    
    template <class T>
    struct NODE {
    NODE<T> *pNext;
    NODE<T> *pPrev;
    T nData;
    };
    
    template <class T>
    void AppendNode(NODE<T> * pNode, NODE<T> **pHead, NODE<T> **pTail);
    
    template <class T>
    void InsertNode(NODE<T> *pNode, NODE<T> *pAfter, NODE<T> **pTail);
    
    template <class T>
    void InsertNodeAt(NODE<T> *pNode, NODE<T> *pAfter, NODE<T> **pHead);
    
    template <class T>
    void RemoveNode(NODE<T> *pNode, NODE<T> **pHead, NODE<T> **pTail);
    
    template <class T>
    void DeleteAllNodes(NODE<T> **pHead, NODE<T> **pTail);
    
    
    template <class T>
    void AppendNode(NODE<T> * pNode, NODE<T> **pHead, NODE<T> **pTail)
    {
    if (*pHead == NULL) {
    *pHead = pNode;
    pNode->pPrev = NULL;
    }
    else {
    (*pTail)->pNext = pNode;
    pNode->pPrev = *pTail;
    }
    *pTail = pNode;
    pNode->pNext = NULL;
    }
    
    // Inserts a node into the list after pAfter
    template <class T>
    void InsertNode(NODE<T> *pNode, NODE<T> *pAfter, NODE<T> **pTail)
    {
    pNode->pNext = pAfter->pNext;
    pNode->pPrev = pAfter;
    
    if (pAfter->pNext != NULL)
    pAfter->pNext->pPrev = pNode;
    else
    *pTail = pNode;
    
    pAfter->pNext = pNode;
    }
    
    template <class T>
    void InsertNodeAt(NODE<T> *pNode, NODE<T> *pAt, NODE<T> **pHead)
    {
    pNode->pNext = pAt;
    pNode->pPrev = pAt->pPrev;
    
    
    if (pAt->pPrev == NULL) //head
    *pHead = pNode;
    else
    pAt->pPrev->pNext = pNode;
    
    pAt->pPrev = pNode;
    }
    
    // Removes the specified node from the list
    template <class T>
    void RemoveNode(NODE<T> *pNode, NODE<T> **pHead, NODE<T> **pTail)
    {
    if (pNode->pPrev == NULL)
    *pHead = pNode->pNext;
    
    else
    pNode->pPrev->pNext = pNode->pNext;
    
    if (pNode->pNext == NULL)
    *pTail = pNode->pPrev;
    
    else
    pNode->pNext->pPrev = pNode->pPrev;
    
    delete pNode;
    }
    
    // Deletes the entire list
    template <class T>
    void DeleteAllNodes(NODE<T> **pHead, NODE<T> **pTail)
    {
    while (*pHead != NULL)
    RemoveNode(*pHead, pHead, pTail);
    }
    
    //-------------------------------------------------------------------------
    
    
    
    //------------------------------------------------------------------------------
    
    class city{
    public:
    city();
    ~city();
    string getName() const;
    void setName(string name);
    bool getIscapital() const;
    void setIscapital(bool iscapital);
    unsigned int getTourist_arrivals() const;
    void setTourist_arrivals(unsigned int tourist_arrivals);
    bool getTravel_by_air() const;
    void setTravel_by_air(bool travel_by_air);
    private:
    string name;
    bool iscapital;
    unsigned int tourist_arrivals;
    bool travel_by_air;
    };
    
    city::city() {
    // TODO Auto-generated constructor stub
    
    }
    
    city::~city() {
    // TODO Auto-generated destructor stub
    }
    
    string city::getName() const
    {
    return name;
    }
    
    void city::setName(string name)
    {
    this->name = name;
    }
    
    bool city::getIscapital() const
    {
    return iscapital;
    }
    
    void city::setIscapital(bool iscapital)
    {
    this->iscapital = iscapital;
    }
    
    unsigned int city::getTourist_arrivals() const
    {
    return tourist_arrivals;
    }
    
    void city::setTourist_arrivals(unsigned int tourist_arrivals)
    {
    this->tourist_arrivals = tourist_arrivals;
    }
    
    bool city::getTravel_by_air() const
    {
    return travel_by_air;
    }
    
    void city::setTravel_by_air(bool travel_by_air)
    {
    this->travel_by_air = travel_by_air;
    }
    
    //-----------------------------------------------------------------------------
    
    class country {
    public:
    country();
    virtual ~country();
    string getName() const;
    void setName(string name);
    string getRegion() const;
    void setRegion(string region);
    string getEconomy() const;
    void setEconomy(string economy);
    unsigned int getTourist_arrivals() const;
    void setTourist_arrivals(unsigned int tourist_arrivals);
    int getTourism_ranking() const;
    void setTourism_ranking(int tourism_ranking);
    NODE<city> * _city;
    
    private:
    string name;
    string region;
    string economy;
    unsigned int tourist_arrivals;
    int tourism_ranking;
    
    };
    
    
    country::country() {
    // TODO Auto-generated constructor stub
    
    }
    
    country::~country() {
    // TODO Auto-generated destructor stub
    }
    
    
    string country::getName() const
    {
    return name;
    }
    
    void country::setName(string name)
    {
    this->name = name;
    }
    
    string country::getRegion() const
    {
    return region;
    }
    
    void country::setRegion(string region)
    {
    this->region = region;
    }
    
    string country::getEconomy() const
    {
    return economy;
    }
    
    void country::setEconomy(string economy)
    {
    this->economy = economy;
    }
    
    unsigned int country::getTourist_arrivals() const
    {
    return tourist_arrivals;
    }
    
    void country::setTourist_arrivals(unsigned int tourist_arrivals)
    {
    this->tourist_arrivals = tourist_arrivals;
    }
    
    int country:: getTourism_ranking()const
    {
    return tourism_ranking;
    }
    
    void country::setTourism_ranking(int tourism_ranking)
    {
    this->tourism_ranking = tourism_ranking;
    }
    
    //-----------------------------------------------------------------------------
    
    
    int main(){
    
    country details;
    
    
    string value;
    cout <<"enter country name ?"<<endl ;
    cin >> value;
    details.setName(value);
    cout<<endl;
    
    string reg;
    cout<<"region?"<<endl;
    cin>>reg;
    details.setRegion(reg);
    cout<<endl;
    
    string eco;
    cout<<"economy?"<<endl;
    cin>>eco;
    details.setEconomy(eco);
    cout<<endl;
    
    unsigned int ari;
    cout<< "tourist arrivals"<<endl;
    cin>>ari;
    details.setTourist_arrivals(ari);
    cout<<endl;
    
    int rank;
    cout<< "tourism ranking"<<endl;
    cin>>rank;
    details.setTourism_ranking(rank);
    cout<<endl;
    
    cout<<" country name: "<<details.getName()<<endl;
    cout<<" region: "<<details.getRegion()<<endl;
    cout<<" economy: "<<details.getEconomy()<<endl;
    cout<<" tourist arrivals: "<<details.getTourist_arrivals()<<endl;
    cout<<" tourism ranking: "<<details.getTourism_ranking()<<endl<<endl;
    
    
    
    system("pause");
    return 0;
    }
    Last edited by SpywareDr; 01-16-2018 at 12:19 PM. Reason: Added [code][/code] tags

  2. #2
    Join Date
    Jan 2018
    Posts
    12
    [Mod - would you add code tags to the code in post #1 so that it's readable!]

  3. #3
    Join Date
    Jan 2018
    Posts
    12

  4. #4
    Join Date
    Feb 2014
    Location
    Riviera Beach, Maryland, USA
    Posts
    44
    Quote Originally Posted by 2kaud View Post
    [Mod - would you add code tags to the code in post #1 so that it's readable!]
    Done

  5. #5
    Join Date
    Jan 2018
    Posts
    12
    The code concerning the list is a great example of how not to do it! Apart from using template<>, this is c code - not c++ code. This is definitely how you don't do it in c++. Considering that post #1 was posted Oct 2017 I am astounded that this sort of c++ coding is still taught and students expected to learn it and program likewise. The best advice I can give is for the teacher to take permanent gardening leave. My sympathy is with the students who think they are being taught c++ when they are not.

    For a simple c++ doubly linked list consider

    Code:
    #include <iostream>
    using namespace std;
    
    template <typename T>
    class dll {
    public:
    	class dllIter;
    
    	dll() {}
    
    	~dll()
    	{
    		clear();
    	}
    
    	dll(const dll& l)
    	{
    		for (const auto& d : l)
    			insertTail(d);
    	}
    
    	dll(dll&& l)
    	{
    		swap(l);
    	}
    
    	dll(initializer_list<T> il)
    	{
    		for (const auto& d : il)
    			insertTail(d);
    	}
    
    	dll& operator=(const dll& l)
    	{
    		dll t(l);
    
    		swap(t);
    		return *this;
    	}
    
    	dll& operator=(dll&& l)
    	{
    		swap(l);
    		return *this;
    	}
    
    	void clear()
    	{
    		for (auto n = head; n;) {
    			auto d = n;
    
    			n = n->next;
    			delete d;
    		}
    
    		head = tail = nullptr;
    	}
    
    	void swap(dll& l)
    	{
    		std::swap(l.head, head);
    		std::swap(l.tail, tail);
    		std::swap(l.cnt, cnt);
    	}
    
    	size_t size() const
    	{
    		return cnt;
    	}
    
    	bool empty() const
    	{
    		return cnt == 0;
    	}
    
    	dllIter insert(const dllIter& it, const T& d)
    	{
    		auto t = new node;
    
    		t->data = d;
    
    		if (head == nullptr)
    			// Empty list
    			head = tail = t;
    		else
    			if (it == end()) {
    				// Insert at tail
    
    				t->prev = tail;
    				tail->next = t;
    				tail = t;
    			} else
    				if (it == begin()) {
    					//Insert at head
    
    					t->next = head;
    					head->prev = t;
    					head = t;
    				} else {
    					it->prev->next = t;
    					t->prev = it->prev;
    					it->prev = t;
    					t->next = it();
    				}
    
    		++cnt;
    		return dllIter(t);
    	}
    
    	dllIter insertHead(const T& d)
    	{
    		return insert(begin(), d);
    	}
    
    	dllIter insertTail(const T& d)
    	{
    		return insert(end(), d);
    	}
    
    	void remove(const dllIter& it)
    	{
    		if (head == nullptr)
    			return;
    
    		if (it == end() || (it()->next == nullptr)) {
    			// Remove from tail
    			auto t = tail;
    
    			if ((tail = tail->prev) == nullptr)
    				head = tail;
    			else
    				tail->next = nullptr;
    
    			delete t;
    		} else
    			if (it == begin() || (it()->prev == nullptr)) {
    				// Remove from head
    				auto h = head;
    
    				if ((head = head->next) == nullptr)
    					tail = head;
    				else
    					head->prev = nullptr;
    
    				delete h;
    			} else {
    				auto n = it();
    
    				n->prev->next = n->next;
    				n->next->prev = n->prev;
    				delete n;
    			}
    
    		--cnt;
    	}
    
    	void removeHead()
    	{
    		remove(begin());
    	}
    
    	void removeTail()
    	{
    		remove(end());
    	}
    
    	dllIter begin() const
    	{
    		return dllIter(head);
    	}
    
    	dllIter end() const
    	{
    		return dllIter();
    	}
    
    	dllIter rbegin() const
    	{
    		return dllIter(tail, false);
    	}
    
    	dllIter rend() const
    	{
    		return dllIter();
    	}
    
    	dllIter find(const T& d) const
    	{
    		for (auto i = begin(); i != end(); ++i)
    			if (d == *i)
    				return i;
    
    		return end();
    	}
    
    private:
    	struct node {
    		T data;
    		node* prev = nullptr;
    		node* next = nullptr;
    
    		node() {}
    	};
    
    	node* head = nullptr;
    	node* tail = nullptr;
    
    	size_t cnt = 0;
    };
    
    template<typename Elem>
    class dll<Elem>::dllIter {
    public:
    	dllIter(node* p = nullptr, bool f = true) : curr(p), forward(f) {}
    
    	dllIter& operator++()
    	{
    		curr = (forward) ? curr->next : curr->prev;
    		return *this;
    	}
    
    	dllIter& operator--()
    	{
    		curr = (forward) ? curr->prev : curr->next;
    		return *this;
    	}
    
    	Elem& operator*() const { return curr->data; }
    	node* operator->() const {return curr;}
    	node* operator()() const {return curr;}
    	bool operator==(const dllIter& b) const { return curr == b.curr; }
    	bool operator!=(const dllIter& b) const { return !operator==(b); }
    
    private:
    	node *curr = nullptr;
    	bool forward = true;
    };
    
    template<typename T>
    void showlist(const dll<T>& dl)
    {
    	for (auto it = dl.begin(); it != dl.end(); ++it)
    		cout << *it << endl;
    
    	cout << endl;
    
    	for (auto it = dl.rbegin(); it != dl.rend(); ++it)
    		cout << *it << endl;
    
    		cout << endl;
    }
    
    int main()
    {
    	dll<int> mylist {1, 2, 3, 4, 5};
    
    	dll<int> l1(mylist);
    
    	for (const auto& d : l1)
    		cout << d << endl;
    
    	cout << endl;
    
    	auto i = mylist.find(3);
    
    	cout << *i << endl << endl;
    
    	mylist.insert(i, 8);
    	showlist(mylist);
    
    	mylist.removeHead();
    	showlist(mylist);
    
    	mylist.removeTail();
    	showlist(mylist);
    
    	auto i2 = mylist.find(3);
    
    	mylist.remove(i2);
    	showlist(mylist);
    }
    Note that this hasn't been extensively tested so there may be issues with some edge cases. If any are found, post a message.

    Usage for city and country classes will follow.............
    Last edited by 2kaud; 01-17-2018 at 12:42 PM.

  6. #6
    Join Date
    Jan 2018
    Posts
    12
    Considering the original post, for a method of using the doubly linked lists for the countries and cities within countries together with a simple menu consider

    Code:
    class city {
    public:
    	city() {}
    
    	city(const city& c) = default;
    	city(city&& c) = default;
    	city& operator=(const city& c) = default;
    	city& operator=(city&& c) = default;
    
    	string getName() const
    	{
    		return name;
    	}
    
    	void setName(const string& nam)
    	{
    		name = nam;
    	}
    
    	bool getIscapital() const
    	{
    		return iscapital;
    	}
    
    	void setIscapital(bool iscap)
    	{
    		iscapital = iscap;
    	}
    
    	unsigned int getTourist_arrivals() const
    	{
    		return tourist_arrivals;
    	}
    
    	void setTourist_arrivals(unsigned int arrivals)
    	{
    		tourist_arrivals = arrivals;
    	}
    
    	bool getTravel_by_air() const
    	{
    		return travel_by_air;
    	}
    
    	void setTravel_by_air(bool by_air)
    	{
    		travel_by_air = by_air;
    	}
    
    private:
    	string name;
    	bool iscapital = false;
    	unsigned int tourist_arrivals = 0;
    	bool travel_by_air = false;
    };
    
    class country {
    public:
    	country() {}
    
    	country(const country& c) = default;
    	country(country&& c) = default;
    	country& operator=(const country& c) = default;
    	country& operator=(country&& c) = default;
    
    	string getName() const
    	{
    		return name;
    	}
    
    	void setName(const string& nam)
    	{
    		name = nam;
    	}
    
    	string getRegion() const
    	{
    		return region;
    	}
    
    	void setRegion(const string& reg)
    	{
    		region = reg;
    	}
    
    	string getEconomy() const
    	{
    		return economy;
    	}
    
    	void setEconomy(const string& econ)
    	{
    		economy = econ;
    	}
    
    	unsigned int getTourist_arrivals() const
    	{
    		return tourist_arrivals;
    	}
    
    	void setTourist_arrivals(unsigned int arrivals)
    	{
    		tourist_arrivals = arrivals;
    	}
    
    	int getTourism_ranking() const
    	{
    		return tourism_ranking;
    	}
    
    	void setTourism_ranking(int ranking)
    	{
    		tourism_ranking = ranking;
    	}
    
    	void add_city(const city& cty)
    	{
    		cities.insertTail(cty);
    	}
    
    	void display_cities() const
    	{
    		for (const auto& c : cities)
    			cout << c.getName() << endl;
    
    		cout << endl;
    	}
    
    	auto find_city(const string& nam) const
    	{
    		for (auto i = cities.begin(); i != cities.end(); ++i)
    			if (i->data.getName() == nam)
    				return i;
    
    		return cities.end();
    	}
    
    	bool remove_city(const string& nam)
    	{
    		if (auto f = find_city(nam); f != cities.end()) {
    			cities.remove(f);
    			return true;
    		}
    
    		return false;
    	}
    
    private:
    	string name;
    	string region;
    	string economy;
    	unsigned int tourist_arrivals = 0;
    	int tourism_ranking = 0;
    
    	dll<city> cities;
    };
    
    void get_country(country& ctrs)
    {
    	string s;
    
    	cout << "Country name: ";
    	cin >> s;
    	ctrs.setName(s);
    
    	cout << "Region: ";
    	cin >> s;
    	ctrs.setRegion(s);
    
    	cout << "Economy: ";
    	cin >> s;
    	ctrs.setEconomy(s);
    
    	int a = 0;
    
    	cout << "Number of tourist arrivals: ";
    	if (!(cin >> a)) {
    		cin.clear();
    		cin.ignore(1000, '\n');
    	}
    	ctrs.setTourist_arrivals(a);
    
    	int r = 0;
    
    	cout << "Tourism ranking: ";
    	if (!(cin >> r)) {
    		cin.clear();
    		cin.ignore(1000, '\n');
    	}
    	ctrs.setTourism_ranking(r);
    }
    
    void get_city(city& cty)
    {
    	string s;
    
    	cout << "City name: ";
    	cin >> s;
    	cty.setName(s);
    
    	cout << "Is a capital (y/n)? ";
    	cin >> s;
    
    	cty.setIscapital(s[0] == 'y');
    
    	int a = 0;
    
    	cout << "Number of Tourist arrivals: ";
    	if (!(cin >> a)) {
    		cin.clear();
    		cin.ignore(1000, '\n');
    	}
    	cty.setTourist_arrivals(a);
    
    	cout << "Travel by air (y/n)? ";
    	cin >> s;
    	cty.setTravel_by_air(s[0] == 'y');
    }
    
    int menu()
    {
    	int o = 9999;
    
    	do {
    		cout << endl;
    		cout << "1. Add a country" << endl;
    		cout << "2. Add a city" << endl;
    		cout << "3. Remove a city" << endl;
    		cout << "4. Remove a country" << endl;
    		cout << "5. Display countries/cities" << endl;
    		cout << "0. Exit" << endl;
    
    		cout << "Option: ";
    		if (!(cin >> o)) {
    			cin.clear();
    			cin.ignore(1000, '\n');
    		}
    
    	} while ((o < 0 || o > 5) && (cout << "Invalid option" << endl));
    
    	return o;
    }
    
    int main()
    {
    	dll<country> countries;
    	country co;
    	city cty;
    	string nam;
    
    	auto fc = [&](const string& nam)
    	{
    		for (auto i = countries.begin(); i != countries.end(); ++i)
    			if (i->data.getName() == nam)
    				return i;
    
    			return countries.end();
    	};
    
    	for (int o; (o = menu()) > 0;)
    		switch (o) {
    			case 1:
    				// Add a country
    				get_country(co);
    				countries.insertTail(co);
    				break;
    
    			case 2:
    				// Add a city
    				cout << "Enter country name: ";
    				cin >> nam;
    
    				if (auto c = fc(nam); c != countries.end()) {
    					get_city(cty);
    					c->data.add_city(cty);
    				} else
    					cout << "Country not found" << endl;
    
    				break;
    
    			case 3:
    				// Remove a city
    				cout << "Enter country name: ";
    				cin >> nam;
    
    				if (auto c = fc(nam); c != countries.end()) {
    					cout << "Enter city name: ";
    					cin >> nam;
    
    					if (!c->data.remove_city(nam))
    						cout << "City not found" << endl;
    				} else
    					cout << "Country not found" << endl;
    
    				break;
    
    			case 4:
    				// Remove a country
    				cout << "Enter country name: ";
    				cin >> nam;
    
    				if (auto c = fc(nam); c != countries.end())
    					countries.remove(c);
    				else
    					cout << "Country not found" << endl;
    
    				break;
    
    			case 5:
    				// Display countries and cities
    				for (const auto& c : countries) {
    					cout << "*" << c.getName() << endl;
    					c.display_cities();
    				}
    				break;
    
    			default:
    				cout << "Bad option" << endl;
    		}
    }
    Again, this hasn't been extensively tested so if any issues are found please post a message.

    Of course, in practice standard STL containers would be used - rather than writing your own container and using that. Writing your own code for an existing stl container is only a nice exercise to develop coding skills and not something that would normally be done - except for the c++ gods that create the STL.


    Note this is c++17 code and has been tested with VS2017 (15.5.4).
    Last edited by 2kaud; 01-18-2018 at 05:54 AM.

  7. #7
    Join Date
    Jan 2018
    Posts
    12
    Using STL map, one simple implementation could be

    Code:
    #include <iostream>
    #include <string>
    #include <map>
    using namespace std;
    
    class city {
    public:
    	city() {}
    
    	city(const city& c) = default;
    	city(city&& c) = default;
    	city& operator=(const city& c) = default;
    	city& operator=(city&& c) = default;
    
    	string getName() const
    	{
    		return name;
    	}
    
    	void setName(const string& nam)
    	{
    		name = nam;
    	}
    
    	bool getIscapital() const
    	{
    		return iscapital;
    	}
    
    	void setIscapital(bool iscap)
    	{
    		iscapital = iscap;
    	}
    
    	unsigned int getTourist_arrivals() const
    	{
    		return tourist_arrivals;
    	}
    
    	void setTourist_arrivals(unsigned int arrivals)
    	{
    		tourist_arrivals = arrivals;
    	}
    
    	bool getTravel_by_air() const
    	{
    		return travel_by_air;
    	}
    
    	void setTravel_by_air(bool by_air)
    	{
    		travel_by_air = by_air;
    	}
    
    private:
    	string name;
    	bool iscapital = false;
    	unsigned int tourist_arrivals = 0;
    	bool travel_by_air = false;
    };
    
    class country {
    public:
    	country() {}
    
    	country(const country& c) = default;
    	country(country&& c) = default;
    	country& operator=(const country& c) = default;
    	country& operator=(country&& c) = default;
    
    	string getName() const
    	{
    		return name;
    	}
    
    	void setName(const string& nam)
    	{
    		name = nam;
    	}
    
    	string getRegion() const
    	{
    		return region;
    	}
    
    	void setRegion(const string& reg)
    	{
    		region = reg;
    	}
    
    	string getEconomy() const
    	{
    		return economy;
    	}
    
    	void setEconomy(const string& econ)
    	{
    		economy = econ;
    	}
    
    	unsigned int getTourist_arrivals() const
    	{
    		return tourist_arrivals;
    	}
    
    	void setTourist_arrivals(unsigned int arrivals)
    	{
    		tourist_arrivals = arrivals;
    	}
    
    	int getTourism_ranking() const
    	{
    		return tourism_ranking;
    	}
    
    	void setTourism_ranking(int ranking)
    	{
    		tourism_ranking = ranking;
    	}
    
    	bool add_city(const city& cty)
    	{
    		if (string nam; !cities.count(nam = cty.getName())) {
    			cities[nam] = cty;
    			return true;
    		}
    
    		return false;
    	}
    
    	void display_cities() const
    	{
    		for (const auto& c : cities)
    			cout << c.first << endl;
    
    		cout << endl;
    	}
    
    	bool city_exists(const string& nam) const
    	{
    		return cities.count(nam) > 0;
    	}
    
    	bool remove_city(const string& nam)
    	{
    		return cities.erase(nam) > 0;
    	}
    
    private:
    	string name;
    	string region;
    	string economy;
    	unsigned int tourist_arrivals = 0;
    	int tourism_ranking = 0;
    
    	map<string, city> cities;
    };
    
    void get_country(country& ctrs, const string& nam = ""s)
    {
    	string s;
    
    	if (nam.empty()) {
    		cout << "Country name: ";
    		cin >> s;
    		ctrs.setName(s);
    	} else
    		ctrs.setName(nam);
    
    	cout << "Region: ";
    	cin >> s;
    	ctrs.setRegion(s);
    
    	cout << "Economy: ";
    	cin >> s;
    	ctrs.setEconomy(s);
    
    	int a = 0;
    
    	cout << "Number of tourist arrivals: ";
    	if (!(cin >> a)) {
    		cin.clear();
    		cin.ignore(1000, '\n');
    	}
    	ctrs.setTourist_arrivals(a);
    
    	int r = 0;
    
    	cout << "Tourism ranking: ";
    	if (!(cin >> r)) {
    		cin.clear();
    		cin.ignore(1000, '\n');
    	}
    	ctrs.setTourism_ranking(r);
    }
    
    void get_city(city& cty, const string& nam = ""s)
    {
    	string s;
    
    	if (nam.empty()) {
    		cout << "City name: ";
    		cin >> s;
    		cty.setName(s);
    	} else
    		cty.setName(nam);
    
    	cout << "Is a capital (y/n)? ";
    	cin >> s;
    
    	cty.setIscapital(s[0] == 'y');
    
    	int a = 0;
    
    	cout << "Number of Tourist arrivals: ";
    	if (!(cin >> a)) {
    		cin.clear();
    		cin.ignore(1000, '\n');
    	}
    	cty.setTourist_arrivals(a);
    
    	cout << "Travel by air (y/n)? ";
    	cin >> s;
    	cty.setTravel_by_air(s[0] == 'y');
    }
    
    int menu()
    {
    	int o = 9999;
    
    	do {
    		cout << endl;
    		cout << "1. Add a country" << endl;
    		cout << "2. Add a city" << endl;
    		cout << "3. Remove a city" << endl;
    		cout << "4. Remove a country" << endl;
    		cout << "5. Display countries/cities" << endl;
    		cout << "0. Exit" << endl;
    
    		cout << "Option: ";
    		if (!(cin >> o)) {
    			cin.clear();
    			cin.ignore(1000, '\n');
    		}
    
    	} while ((o < 0 || o > 5) && (cout << "Invalid option" << endl));
    
    	return o;
    }
    
    int main()
    {
    	map<string, country> countries;
    	country co;
    	city cty;
    
    	for (int o; (o = menu()) > 0;)
    		switch (string nam; o) {
    			case 1:
    				// Add a country
    				cout << "Country name: ";
    				cin >> nam;
    
    				if (!countries.count(nam)) {
    					get_country(co, nam);
    					countries[nam] = co;
    				} else
    					cout << "Country already exists" << endl;
    				break;
    
    			case 2:
    				// Add a city
    				cout << "Enter country name: ";
    				cin >> nam;
    
    				if (auto c = countries.find(nam); c != countries.end()) {
    					string cn;
    
    					cout << "City name: ";
    					cin >> cn;
    
    					if (!c->second.city_exists(cn)) {
    						get_city(cty, cn);
    						if (!c->second.add_city(cty))
    							cout << "Problem adding city" << endl;
    					} else
    						cout << "City already exists" << endl;
    				} else
    					cout << "Country not found" << endl;
    
    				break;
    
    			case 3:
    				// Remove a city
    				cout << "Enter country name: ";
    				cin >> nam;
    
    				if (auto c = countries.find(nam); c != countries.end()) {
    					cout << "Enter city name: ";
    					cin >> nam;
    
    					if (!c->second.remove_city(nam))
    						cout << "City not found" << endl;
    				} else
    					cout << "Country not found" << endl;
    
    				break;
    
    			case 4:
    				// Remove a country
    				cout << "Enter country name: ";
    				cin >> nam;
    
    				if (auto c = countries.find(nam); c != countries.end())
    					countries.erase(c);
    				else
    					cout << "Country not found" << endl;
    
    				break;
    
    			case 5:
    				// Display countries and cities
    				for (const auto& c : countries) {
    					cout << "*" << c.second.getName() << endl;
    					c.second.display_cities();
    				}
    				break;
    
    			default:
    				cout << "Bad option" << endl;
    		}
    }
    [Note VS2017 c++17 code]

    This is more like what I would be expecting c++ 101 students to be able to code.
    Last edited by 2kaud; 01-18-2018 at 06:00 AM.

Similar Threads

  1. doubly linked lists
    By noobie_coder in forum C++
    Replies: 4
    Last Post: 10-04-2008, 03:35 AM
  2. Doubly linked lists using classes
    By reddy in forum C++
    Replies: 0
    Last Post: 02-22-2002, 11:13 AM
  3. doubly linked lists
    By leonardo in forum C++
    Replies: 2
    Last Post: 12-10-2001, 11:18 AM
  4. doubly linked lists
    By leonardo in forum C++
    Replies: 0
    Last Post: 12-10-2001, 09:09 AM
  5. doubly linked lists
    By leonardo in forum C++
    Replies: 0
    Last Post: 12-10-2001, 09:09 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center