Question: You are to develop a program to read Baseball player statistics from an input file. Each player should be stored in a Player object. This

You are to develop a program to read Baseball player statistics from an input file. Each player should be stored in a Player object. This program builds on to the requirements for Program #2 and #3. Please see the earlier assignments for the definition of a Player Object.

This will read in the same type of player data from an input file and write the results to the screen New Requirements You are to implement our collection of baseball players as a binary tree, ordered by the player's name. (Lastname first, then firstname, in the event of people with the same last name). Your Tree class must implement at least the following methods, and any supporting methods you need. Reminder: Because many tree operations are recursive using a node pointer to a root or subroot as input, many operations have a private version that is called with the correct pointer and a public version presented to the user who has no concept of the internal implementation of the tree.

default constructor and destructor

insert - to add a new player to the tree

free - to clean up a tree and free all of the nodes in the tree

count - to return a count of all players in the tree

display - to display the player records, in appropriate order.

updateAvg - to update a particular player's batting average

find - find a player by name As with the prior programs, you must write a main program to adequately test your methods.

Additionally, prompt the user for the name of a player and a new batting average. Find that player in the tree and update his average to the new value. If the player is not found in the tree, indicate that to the user with a message. Prompt the user to perform this operation until the user is ready to quit the program. After the user is finished testing the search and replace for batting averages, print the contents of the tree to the screen in sorted order (ascending) and in reverse order (descending).

Program 3 is:

Main:

#include  
#include  
#include "OrderedPlayerList.h" 
using namespace std; 
 
int main (void) 
{ 
 const int FNLENGTH = 100; // use a reasonable size for filenames 
 char inputFileName[FNLENGTH]; // create buffers to store filenames 
 char outputFileName[FNLENGTH]; 
 ifstream inFile; // create file objects for our 2 files 
 ofstream outFile; 
 
 Player currentPlayer; // use to store the next player from the file, or a found player from the list 
 OrderedPlayerList myList; // use to store the player list 
 
 int i; // loop counter 
 
 cout << "Testing a locate in an empty list to make sure it does not crash or error! "; 
 myList.locate("Chipper", "Jones", cout); 
 cout << " "; 
 
 
 // Prompt the user and open the input data file 
 cout << "Please enter the name of your input data file: "; 
 cin >> inputFileName; 
 
 inFile.open(inputFileName); 
 if (inFile.fail()) { // file open failed 
 cout << " Error opening input file. Cannot process player data. Exiting Program. " << endl; 
 return 0; // NOTE THIS IS THE ONLY TIME I ALLOW AN EMBEDDED RETURN or BREAK type exit IN A PROGRAM 
 } 
 
 // file opened successfully 
 
 while (!inFile.eof()) { // as long as there are lines of data to be read in 
 // read in a player 
 currentPlayer.Read(inFile); 
 // store in list 
 myList.add(currentPlayer); 
 } 
 inFile.close(); 
 
 // Now write the player data to the desired output file 
 cout << "Please enter the name of your output data file: "; 
 cin >> outputFileName; 
 outFile.open(outputFileName); // as long as there is space on disk, this won't fail 
 
 outFile << "There were " << myList.getSize() << " players in the input data file: " << endl; 
 myList.resetToEnd(); // get the list ready for iteration (BACKWARDS JUST TO CHECK MY LINKS!!! 
 while (myList.getPrev(currentPlayer)) // as long as getPrev returns TRUE for success! 
 { 
 currentPlayer.Write(outFile); // write the most recently retrieved player to the output file 
 outFile << endl; 
 } 
 
 outFile.close(); 
 
 cout << " Your output is stored in the file named " << outputFileName << endl; 
 
 cout << " Let's test your find operation a couple of times! " ; 
 
 if(myList.locate("Chipper", "Jones", cout)) 
 cout << " --- was found in the list!"; 
 else 
 cout << " --- 2 nearest found the list!"; 
 cout <<" "; 
 
 // make sure to test where we go off of the end of the list 
 if(myList.locate("Mark", "Jones", cout)) 
 cout << " --- was found in the list!"; 
 else 
 cout << " --- 2 nearest found the list!"; 
 cout << " "; 
 
 cout << " End Program 3" << endl; 
 
 return 0; 
} 

Ordered List:

OrderedPlayerList::OrderedPlayerList() { 
 m_length = 0; 
 pFirst = NULL; // reflect the fact that there are no nodes in this List 
 pCurrent = NULL; 
} 
 
//------------------------------------------------------------------------ 
// isEmpty: bool 
// returns true if the List is empty 
//------------------------------------------------------------------------ 
bool OrderedPlayerList::isEmpty() { 
 return pFirst == NULL; // use our List pointer now 
} 
//------------------------------------------------------------------------ 
// isFull: bool 
// returns true if the List is full to capacity 
//------------------------------------------------------------------------ 
bool OrderedPlayerList::isFull() { 
 return false; // there is no more restriction on the size of the List! 
} 
 
//------------------------------------------------------------------------ 
// add(Player): bool 
// attempts to add an item to the List. If the List is full return false, 
// if successful, return true (true represents success) 
// SORTED VERSION, now we need to find which nodes our new node must go between 
//------------------------------------------------------------------------ 
bool OrderedPlayerList::add(Player newPlayer) // add a new item to the List 
{ 
 Node *pNew; // pointer to a new node 
 Node *p, *q; // our pointers that traverse the List looking for a spot to insert 
 pNew = new Node(newPlayer); 
 if (pNew == NULL) // then the allocate did not succeed which would be a critical memory failure! 
 { 
 return false; // did not succeed 
 } 
 
 // LOGIC TO STEP THROUGH THE NODES OF A SORTED List TO FIND AN INSERTION----- 
 // SPOT---------------------------------------------------------------------- 
 p = pFirst; 
 q = NULL; // q will be 1 node prior to the one we are looking at 
 while (p != NULL && p->item.lessThan(newPlayer) ) // we are still looking for a spot 
 { 
 q = p; // save the node before the spot 
 p = p->pNext; // move over 1 
 } 
 
 // At this point, q points to the node before and p points to the node that needs to be after 
 // if q is null, this our new first node 
 
 if (q == NULL) { 
 pNew->pNext = pFirst; // put our new node in front of pFirst 
 if (pFirst != NULL) { // PROG3 MOD: IF THERE IS ACTUALLY A NODE THERE, make it point back to our new node 
 pFirst->pPrev = pNew; 
 } 
 pFirst = pNew; // then make our new node the new front of the List 
 } 
 else { 
 q->pNext = pNew; // pNew comes after q 
 pNew->pPrev = q; 
 pNew->pNext = p; // and p comes after pNew 
 if (p) p->pPrev = pNew; 
 } 
 
 m_length++; // count it 
 
 return true; // add succeeded 
} 
 
//------------------------------------------------------------------------ 
// remove(Player d): bool 
// locate and remove the given item from the list. If it is in there, 
// we will have to relink the nodes and free the no longer needed node 
//------------------------------------------------------------------------- 
bool OrderedPlayerList::remove(Player player) // remove an item from the List 
{ 
 bool found = false; // return true if successfully removed a node, assume false to begin with 
 
 // find a node and remove it 
 
 Node *p; // node we are looking at 
 
 p = pFirst; 
 // PROG3 MOD: don't need q to follow. If p finds a node we can look back 
 found = false; 
 while (p != NULL && (!p->item.equals(player))) // as long as there is a node and it is not the one we are looking for 
 { 
 p = p->pNext; // move p over to the next node 
 } 
 
 if (p != NULL) // need to unlink the node p and free it 
 { 
 if (p->pPrev == NULL) { // if the node in front of p is NULL then we are removing the first node from the List 
 pFirst = p->pNext; 
 delete p; 
 } 
 else { // p is not the first node in thie List, so 
 p->pPrev->pNext = p->pNext; 
 if (p->pNext != NULL) { // PROG3 MOD: ahead to see if there is a node that needs to link back 
 p->pNext->pPrev = p->pPrev; 
 } 
 delete p; 
 } 
 found = true; 
 } 
 
 m_length--; 
 return found; 
} 
//------------------------------------------------------------------------ 
// getSize: int 
// return the internal length of the List, ie number of items stored 
//------------------------------------------------------------------------ 
int OrderedPlayerList::getSize() 
{ 
 return m_length; 
} 
//------------------------------------------------------------------------ 
// resetToStart: void 
// resets the internal iterator counter to the beginning of the List 
//------------------------------------------------------------------------ 
void OrderedPlayerList::resetToStart() // sets the List iterator to the start of the List 
{ 
 pCurrent = pFirst; // copy the location of the first node into our iterator 
} 
//------------------------------------------------------------------------ 
// getNext: Player 
// returns a copy of the next item in the List - as a parameter 
// NOTE it is up to the user to check to see if there are more items 
// when iterating! 
// VERSION 2: MODIFIED to return a success status 
//------------------------------------------------------------------------ 
bool OrderedPlayerList::getNext(Player &item) { 
 bool success; 
 if (pCurrent != NULL) { // NEVER TRY TO ACCESS A NULL POINTER'S DATA! 
 item = pCurrent->item; // copy the item stored into parameter, to pass back to caller 
 pCurrent = pCurrent->pNext; // move to next node in the linked List 
 success = true; 
 } 
 else 
 success = false; 
 return success; 
} 
 
//------------------------------------------------------------------------ 
// resetToEnd: void 
// resets the internal iterator counter to the end of the List 
//------------------------------------------------------------------------ 
void OrderedPlayerList::resetToEnd() // sets the List iterator to the start of the List 
{ 
 pCurrent = pFirst; // copy the location of the first node into our iterator 
 if (pFirst) { // if the list is not empty move to the end 
 while (pCurrent->pNext != NULL) { 
 pCurrent = pCurrent->pNext; 
 } 
 } 
} 
//------------------------------------------------------------------------ 
// getPrev: Player 
// returns a copy of the prior item in the List - as a parameter 
// ADDED with program 3 just because I felt like it 
//------------------------------------------------------------------------ 
bool OrderedPlayerList::getPrev(Player &item) { 
 bool success; 
 if (pCurrent != NULL) { // NEVER TRY TO ACCESS A NULL POINTER'S DATA! 
 item = pCurrent->item; // copy the item stored into parameter, to pass back to caller 
 pCurrent = pCurrent->pPrev; // move backward in the doubly linked list 
 success = true; 
 } 
 else 
 success = false; 
 return success; 
} 
 
 
//------------------------------------------------------------------------ 
// clear: void 
// Clears the MEMORY used up by our List. 
// IMPORTANT: When working with dynamic memory allocation, it is ESSENTIAL that 
// the user frees memory nodes when done! 
// THIS IS A HANDY UTILITY FOR A DESTRUCTOR! 
//------------------------------------------------------------------------ 
void OrderedPlayerList::clear() // sets the List iterator to the start of the List 
{ 
 Node *p, *q; 
 p = pFirst; 
 while (p != NULL) { 
 q = p->pNext; // don't lose the link! 
 delete p; // free the node that p points to 
 p = q; // get ready to move over 1 node 
 } 
 pFirst = NULL; 
 pCurrent = NULL; 
} 
 
//------------------------------------------------------------------------ 
// locate : PROG3 MOD 
// add a method to handle the new requirement 
//------------------------------------------------------------------------ 
bool OrderedPlayerList::locate(string first, string last, ostream &out) { 
 bool found = false; 
 bool notinlist = false; 
 Player temp; 
 
 temp.setFirstName(first); // let's use a temporary player object for comparisons 
 temp.setLastName(last); 
 
 Node *p, *q; // use p, q to search for the player in this list 
 p = pFirst; // start at beginning of list 
 q = NULL; 
 while (!found && p != NULL && !notinlist) { 
 if (temp.equals(p->item)) 
 found = true; 
 else if (temp.lessThan(p->item)) { // PROG3 MOD: we have gone past the location where our node should be!! 
 notinlist = true; 
 } 
 else { 
 q = p; // need this to know if we've gone off the end of a list 
 p = p->pNext; 
 } 
 } 
 if (found) { // PROG3 MOD 
 p->item.Write(out); 
 } 
 else { // not in the list, but we should have stopped at nearest item or gone off the end of the list! 
 if (p) { // make sure not null, print p and either the one before or after 
 if (p->pPrev) { 
 p->pPrev->item.Write(out); 
 p->item.Write(out); 
 } 
 else { 
 p->item.Write(out); 
 if (p->pNext) p->pNext->item.Write(out); 
 } 
 } 
 else if (q) { // we went off the end of the list, but make sure there is actually at least 1 node there! 
 if (q->pPrev) q->pPrev->item.Write(out); 
 q->item.Write(out); 
 } 
 else { // there appear to be no nodes in this list! 
 out << "There appear to be no Players in your list."; 
 } 
 } 
 return found; 
} 
 
 
 
//------------------------------------------------------------------------ 
// ~OrderedPlayerList: Destructor 
// Clears the MEMORY used up by our List. when theOrderedPlayerList is no 
// longer in use 
//------------------------------------------------------------------------ 
OrderedPlayerList::~OrderedPlayerList() { 
 clear(); // use our utility 
} 
 
 
//------------------------------------------------------------------------ 
// dump: void 
// Write a loop to step through the nodes in the List and print their 
// items to the output stream 
//------------------------------------------------------------------------ 
void OrderedPlayerList::dump(ostream &o) 
{ 
 // TODO: Exercise left for the student 
} 

Ordered List 2: 
class Node { 
public: 
 Player item; // storage space for a Player 
 Node *pNext; // a pointer to the next dynamically allocated Node in the list 
 Node *pPrev; // a pointer to the prior node in the list 
 Node(const Player &player) // used to copy item into newly created nodes for our list 
 { 
 item = player; 
 pNext = NULL; // set link to a valid non-node value 
 pPrev = NULL; 
 } 
}; 
 
 
class OrderedPlayerList { 
 Node *pFirst; // a pointer that always points to the first item in the list 
 int m_length; // current length of the list (number of items stored) 
 Node *pCurrent; // used for iterations through the list 
public: 
 // default constructors and destructor 
 OrderedPlayerList(); 
 ~OrderedPlayerList(); 
 
 // public member functions 
 bool isEmpty(); 
 bool isFull(); 
 bool add(Player player); // add a player to the list 
 bool remove(Player player); // remove a player from the list 
 
 int getSize(); // returns the count of items stored in the list 
 void resetToStart(); // sets the list iterator to the start of the list 
 void resetToEnd(); // PROG3 MOD: maybe we want to iterate backwards 
 bool getNext(Player &); // gets a copy of the next item from the list when iterating 
 bool getPrev(Player &); // gets prev player when iterating backwards 
 void dump(ostream &); // dumps a list to an output stream, handy for printing everything, or debugging 
 void clear(); // utility to clear out a list and make it ready for new data 
 
 // PROG3: NEW FUNCTION 
 bool locate(string, string, ostream &); // use to find and print a player by first and last name or nearest 2 
}; 
Player: 
#include  
#include  
#include  
#include "Player.h" 
using namespace std; 
 
// Default constructor - set player to predefined values 
Player::Player() { 
 // use the Initialize method since we have one 
 Initialize("unknown", "unknown", "tbd", 0.0); 
} 
 
// copies data into the object with some simple formatting and 
// data checking 
void Player::Initialize(string first, string last, string pos, double avg) 
{ 
 m_firstName = first; 
 m_lastName = last; 
 m_position = pos; 
 if (avg < 0) avg = -avg; // at least try to correct 
 m_battingAverage = avg; 
} 
 
// define methods to read and write simple versions of player data 
// to/from streams 
 
// Read assumes the player's data is in the input stream in the format: 
// firstname lastname position average with only spaces between the data 
// no other separator characters are used. This will not work if a player's 
// name has embedded spaces! 
void Player::Read(istream &input) { 
 char temp[100]; // using a temporary buffer to read input from stream 
 input >> temp; 
 m_firstName = temp; 
 input >> temp; 
 m_lastName = temp; 
 input >> temp; 
 m_position = temp; 
 input >> m_battingAverage; 
} 
 
// Write the Player data to an output stream with simple formatting 
void Player::Write(ostream &out) { 
 out << m_lastName << ", " << m_firstName << ": " << m_position; 
 out << fixed; 
 out << setprecision(3); 
 out << " (" << m_battingAverage << ") "; 
} 
 
// define get/sets as needed 
double Player::getBattingAverage() { return m_battingAverage; } 
string Player::getFirstName() { return m_firstName; } 
string Player::getLastName() { return m_lastName; } 
string Player::getFullName() { return m_firstName + " " + m_lastName; } 
string Player::getPosition() { return m_position; } 
 
void Player::setFirstName(string name) { m_firstName = name; } 
void Player::setLastName(string name) { m_lastName = name; } 
 
// lessThan function returns true if this Player is less than the one 
// passed in (comparison done lastname, firstname) 
// TBD - modify these to handle case-insensitive comparisons! 
bool Player::lessThan(const Player &player) const 
{ 
 bool less; 
 if (m_lastName.compare(player.m_lastName) < 0) // less than is true 
 less = true; 
 else if (m_lastName.compare(player.m_lastName) == 0 && m_firstName.compare(player.m_firstName) < 0) 
 less = true; 
 else 
 less = false; 
 return less; 
} 
 
bool Player::equals(const Player &player) const 
{ 
 if (m_lastName.compare(player.m_lastName) == 0 && m_firstName.compare(player.m_firstName) == 0) 
 return true; 
 else 
 return false; 
} 

Player2:

#include  
using namespace std; 
 
class Player { 
 string m_firstName; // player's first name 
 string m_lastName; // player's last name 
 string m_position; // player's primary position 
 double m_battingAverage; // batting average 
 
public: 
 // Default Constructor 
 Player(); 
 // copies data into the object with some simple formatting and 
 // data checking 
 void Initialize(string, string, string, double); 
 
 // define methods to read and write simple versions of player data 
 // to/from streams 
 void Read(istream&); 
 void Write(ostream&); 
 
 // define get/sets as needed 
 double getBattingAverage(); 
 string getFirstName(); 
 string getLastName(); 
 string getFullName(); 
 string getPosition(); 
 
 void setFirstName(string); 
 void setLastName(string); 
 
 // added for maintaining ordered list by name 
 bool lessThan(const Player &player) const; 
 bool equals(const Player &player) const; 
}; 

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!