Reputation: 11
Hi right now I am trying to rewrite my code so it can take in each item of the linked list as a string reading a first and last name. At the moment I got the program to work, but when I enter a first and last name the program treats them as separate elements instead of one single entity. So basically I want "Jack Frost" to have a linked list length of 1 instead 2, and then I try to prompt the user to enter a first and last name so they are deleted from the list. Hopefully someone can help. I am posting the tester program I made and the header file. Fair warning the header file is a bit long. The tester program needs to print the full list line by line with first and last name.
Update: I do prompt the user to enter first and last name in the same line. They are for some reason being counted as two separate elements, I need to them to be considered on element together.
#ifndef H_LinkedListType
#define H_LinkedListType
#include <iostream>
//Definition of the node
template <typename Type>
struct nodeType
{
Type info;
nodeType<Type> *link;
};
template<typename Type>
class linkedListType
{
public:
const linkedListType<Type>& operator=(const linkedListType<Type>&);
//Overload the assignment operator
void initializeList();
//Initialize the list to an empty state
//Post: first = NULL, last = NULL
bool isEmptyList();
//Function returns true if the list is empty;
//otherwise, it returns false
bool isFullList();
//Function returns true if the list is full;
//otherwise, it returns false
void print();
//Output the data contained in each node
//Pre: List must exist
//Post: None
int length();
//Return the number of elements in the list
void destroyList();
//Delete all nodes from the list
//Post: first = NULL, last = NULL
void retrieveFirst(Type& firstElement);
//Return the info contained in the first node of the list
//Post: firstElement = first element of the list
void search(const Type& searchItem);
//Outputs "Item is found in the list" if searchItem is in
//the list; otherwise, outputs "Item is not in the list"
void insertFirst(const Type& newItem);
//newItem is inserted in the list
//Post: first points to the new list and the
// newItem inserted at the beginning of the list
void insertLast(const Type& newItem);
//newItem is inserted in the list
//Post: first points to the new list and the
// newItem is inserted at the end of the list
// last points to the last node in the list
void deleteNode(const Type& deleteItem);
//if found, the node containing deleteItem is deleted
//from the list
//Post: first points to the first node and
// last points to the last node of the updated list
linkedListType();
//default constructor
//Initializes the list to an empty state
//Post: first = NULL, last = NULL
linkedListType(const linkedListType<Type>& otherList);
//copy constructor
~linkedListType();
//destructor
//Deletes all nodes from the list
//Post: list object is destroyed
protected:
nodeType<Type> *first; //pointer to the first node of the list
nodeType<Type> *last; //pointer to the last node of the list
};
template<typename Type>
void linkedListType<Type>::initializeList()
{
destroyList(); //if the list has any nodes, delete them
}
template<typename Type>
void linkedListType<Type>::print()
{
nodeType<Type> *current; //pointer to traverse the list
current = first; //set current so that it points to
//the first node
while(current != NULL) //while more data to print
{
cout<<current->info<<" ";
current = current->link;
}
} //end print
template<typename Type>
int linkedListType<Type>::length()
{
int count = 0;
nodeType<Type> *current; //pointer to traverse the list
current = first;
while (current!= NULL)
{
count++;
current = current->link;
}
return count;
} // end length
template<typename Type>
void linkedListType<Type>::search(const Type& item)
{
nodeType<Type> *current; //pointer to traverse the list
bool found;
if(first == NULL) //list is empty
cout<<"Cannot search an empty list. "<<endl;
else
{
current = first; //set current pointing to the first
//node in the list
found = false; //set found to false
while(!found && current != NULL) //search the list
if(current->info == item) //item is found
found = true;
else
current = current->link; //make current point to
//the next node
if(found)
cout<<"Item is found in the list."<<endl;
else
cout<<"Item is not in the list."<<endl;
} //end else
} //end search
template<typename Type>
void linkedListType<Type>::insertLast(const Type& newItem)
{
nodeType<Type> *newNode; //pointer to create the new node
newNode = new nodeType<Type>; //create the new node
newNode->info = newItem; //store the new item in the node
newNode->link = NULL; //set the link field of new node
//to NULL
if(first == NULL) //if the list is empty, newNode is
//both the first and last node
{
first = newNode;
last = newNode;
}
else //if the list is not empty, insert newNnode after last
{
last->link = newNode; //insert newNode after last
last = newNode; //make last point to the actual last node
}
} //end insertLast
template<typename Type>
void linkedListType<Type>::deleteNode(const Type& deleteItem)
{
nodeType<Type> *current; //pointer to traverse the list
nodeType<Type> *trailCurrent; //pointer just before current
bool found;
if(first == NULL) //Case 1; list is empty.
cout<<"Can not delete from an empty list.\n";
else
{
if(first->info == deleteItem) //Case 2
{
current = first;
first = first ->link;
if(first == NULL) //list had only one node
last = NULL;
delete current;
}
else //search the list for the node with the given info
{
found = false;
trailCurrent = first; //set trailCurrent to point to
//the first node
current = first->link; //set current to point to the
//second node
while((!found) && (current != NULL))
{
if(current->info != deleteItem)
{
trailCurrent = current;
current = current-> link;
}
else
found = true;
} // end while
if(found) //Case 3; if found, delete the node
{
trailCurrent->link = current->link;
if(last == current) //node to be deleted was
//the last node
last = trailCurrent; //update the value of last
delete current; //delete the node from the list
}
else
cout<<"Item to be deleted is not in the list."<<endl;
} //end else
} //end else
} //end deleteNode
#endif
This is the tester program below.
//This program tests various operation of a linked list
#include "stdafx.h"
#include <string>//Need to import string to the class to be able to use that type
#include <iostream>
#include "linkedList.h"
using namespace std;
int main()
{
linkedListType<string> list1, list2;
int num;
string name;//Input from the user
//cout<<"Enter numbers ending with -999"
//<<endl;
//cin>>num;
cout<<"Please enter first and last name in each line, enter end to close program" //Prompting the user to enter first and last name on each line til they specify "end"
<<endl;
cin>>name;
while(name != "end")//Checks if user entered name if not it will proceed to keep prompting the user
{
list1.insertLast(name);//inserts the name at the end of the list
cin>>name;
}
cout<<endl;
cout<<"List 1: ";
list1.print();//Prints all the names line by line
cout<<endl;
cout<<"Length List 1: "<<list1.length()//Gives length of how many names are in the list
<<endl;
list2 = list1; //test the assignment operator
cout<<"List 2: ";
list2.print();
cout<<endl;
cout<< "Length List 2: "<< list2.length() <<endl;
cout<< "Enter the name to be " << "deleted: ";
cin>>num;
cout<<endl;
list2.deleteNode(name);
cout<<"After deleting the node, "
<< "List 2: "<<endl;
list2.print();
cout<<endl;
cout<<"Length List 2: "<<list2.length()
<<endl;
system("pause");
return 0;
Upvotes: 0
Views: 3399
Reputation: 4191
Instead of name and surname in two lines get them in one line as following:
char name[256]
std::cout << "Please, enter your name: and surname";
std::cin.getline (name,256);
To split name and surname copy/paste this code to your solution.
std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim)) {
elems.push_back(item);
}
return elems;
}
std::vector<std::string> split(const std::string &s, char delim) {
std::vector<std::string> elems;
split(s, delim, elems);
return elems;
}
Then divide name and surname you will write
vector<string> person = split(name, ' ');
person.at(0) // the name of the person
person.at(1) //the surname of the person
Upvotes: 1
Reputation: 57728
The easiest solution is to create a structure containing your two strings:
struct Person_Name
{
std::string first;
std::string last;
};
Then you can "pass" the structure as the type in your linked list:
LinkedListType<Person_Name> people;
You may have to adjust the "genericity" or assumptions made by the list or add functionality to the Person_Name to make it conform to the list's interface.
Edit 1: Comparing the data
The linked list is probably using operator<
to order the nodes in the list. So you will have to add that overloaded operator to your structure:
struct Person_Name
{
std::string first_name;
std::string second_name;
bool operator<(const& Person_Name pn) const
{
if (second_name == pn.second_name)
{
return first_name < pn.first_name;
}
return second_name < pn.second_name;
}
};
You can implement operator==
in a similar fashion.
Upvotes: 1
Reputation: 4432
cin input is separated also with space, in your sample code, in the last loop when read cin>>name;
name would take value for all spaces and new line separated words.
Use this instead:
std::string name;
std::getline(std::cin, name);
Upvotes: 3