Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

C++ Program. Please help me fix the error. Also post the output. Write a program

ID: 3847789 • Letter: C

Question

C++ Program. Please help me fix the error. Also post the output.

Write a program for a police department that has collected a database of information on various suspects for a given crime. (Luckily for you, the department is only investigating one crime at a time.) Each suspect has a set of attributes, such as shifty eyes, a limp, or a parrot on his shoulder. The maximum number of such attributes for any suspect is not known. Your program accepts commands to manipulate the database in order to narrow down the list of suspects, in the hope of pinpointing the villain.

Input

The retained criminal information, generated by the previous execution of this program, is input from file "Criminal.mf" at the beginning of each execution of the program.

The user inputs commands from the keyboard, in the format shown below. Names and attributes are strings of no more than 20 characters. The program should not be case sensitive (e.g., 'JOE' and 'Joe' are the same name). To simplify the processing, you can assume that names are unique; that is, no two criminals use the same professional handle. The commands are discussed in detail in the Command Processing instructions below.

Output

Responses to user commands are to be written to the screen, as described in the Command Processing instructions below.

Echo print each command and show the results of any PRINT commands in a file called "Criminal.trn". You may determine the format of the information in this file; it should be labeled and formatted clearly. A hard copy of this file is turned in with your program for grading.

If any new suspects were added (see ADD command), file "Criminal.mf" must be rewritten to contain the updated collection of criminal information.

Command Processing

New suspects can be added to the collection of criminal information using the ADD command. An inquiry consists of a set of commands with respect to a single crime, at the end of which the crime is assumed to be solved. An inquiry must be completed within the execution of the program; it cannot be "saved" to finish on a subsequent execution. After an inquiry is complete, a new inquiry (the investigation of another crime) can begin. Each new inquiry starts over with the entire collection of suspects.

Command

Processing

ADD

Add a suspect to the Suspects data structure. Prompt the user for the suspect's name and a list of attributes. ADD commands can be issued only before an inquiry begins.

INQUIRY

Prompt user for code name of this inquiry. Once the inquiry has begun, do not allow the user to issue the ADD command until this inquiry is complete.

TIP

Prompt user for the tip information (a particular attribute). Process the tip, reducing the set of current suspects by deleting suspects who do not match the attribute mentioned in the tip. If there is only one suspect left in the set of active suspects, print out a message indicating that the crime is solved. Be sure to include the suspect's name and inquiry code name. This terminates the current inquiry.

CHECK

Prompt the user for a suspect's name. Check the set of active suspects to see if this name is there; print out an appropriate response.

PRINT

Print the set of active suspects (those who have not yet been eliminated).

QUIT

If any new suspects have been added during this execution of the program, rewrite the "Criminal.mf" file. Be careful about how you go about saving the records; the traversal order affects the shape of the tree that is built on the next execution of the program. Terminate the program.

Sample Input

(Some of the labels shown in the sample input are not typed in by the user, but are only printed for clarity. For this example, the "Criminal.mf" file is empty and all the potential suspects are added by command.)

ADD Name: Quickdraw McGraw

Attributes: has a Texas accent

has a body guard

is computer literate

ADD Name: Twingun Morgan

Attributes: has a New York accent

has red hair

smokes cigars

ADD Name: Jackda Ripper

Attributes: has a body guard

bites his fingernails

carries a knife

is computer literate

ADD Name: Annie Getcher Gunn

Attributes: has a New York accent

has red hair

eats Fritos

smokes cigars

ADD Name: Slowdrawl Raul

Attributes: has a Texas accent

carries a knife

is computer literate

eats Fritos

ADD Name: Sloan de Uptake

Attributes: has a body guard

has red hair

bites his fingernails

is computer literate

INQUIRY Code Name: Bang Bang

TIP Tip Info: has a New York accent

CHECK Quickdraw McGraw

TIP Tip Info: has red hair

CHECK Annie Getcher Gunn

TIP Tip Info: eats Fritos

INQUIRY Code Name: Holdup

TIP Tip Info: has a Texas accent

CHECK Slowdrawl Raul

CHECK Sloan de Uptake

TIP Tip Info: is computer literate

INQUIRY Code Name: Tough Stuff

TIP Tip Info: bites his fingernails

PRINT

CHECK Twingun Morgan

TIP Tip Info: has a body guard

CHECK Slowdrawl Raul

TIP Tip Info: is computer literate

QUIT

Data Structures

There is no upper bound to the number of suspects or number of attributes for a given suspect. You cannot use an array-based list to store the suspects or the attributes for a given suspect.

The CHECK operation must be very efficient, because suspects are continually being pulled off the street for questioning and we must decide whether to let them go or ruthlessly interrogate them. Using a simple linked list to store the suspects is not sufficient. You must use a binary search tree. Suspects must be actually deleted from the structure when they are eliminated by TIP information. Because you destroy the list of suspects, as suspects are eliminated by TIP information, each inquiry should work on a copy of the original tree.

TIP is executed much less often than CHECK and hence can be less efficient. It is acceptable if processing a TIP command requires searching the whole data structure of (active) suspects. Thus, a list of attributes can be stored with each suspect. You do not have to link all the suspects with the same attributes together. (This could potentially make for a much faster TIP operation.) You may do this if you want, but it complicates things.

Deliverables

Your design and CRC cards for any classes

A listing of any test driver necessary to check classes

A listing of the test plan for any class as input to the driver

A listing of the source code

A listing of the test plan as input to the program

A listing of the output from the test run

Here is my Program

******************************************

BinarySearchTree.cpp

#include "BinarySearchTree.h"

#include <iostream>

#include <fstream>

using namespace std;

//Begin BinarySearchTree Class Functions Definitions

//Functions: Constructor, sets root to null

//Pre: None

//Post: Root is Null

BinarySearchTree::BinarySearchTree()

{

   //set root to NULL

   root = NULL;

}

//Functions: Destructor, deletes a binary search Tree

//Pre: None

//Post: Tree is deleted

BinarySearchTree::~BinarySearchTree()

{

   //calls Destroy passing root of binary search tree

   Destroy(root);

}

//Funcions: MakeEmpty, removes all the nodes from the tree

//Pre: None

//Post: Nodes are deleted, root is set to NULL

void BinarySearchTree::makeEmpty()

{

   //calls Destroy passing root of binary search tree

   Destroy(root);

   //Set root to null

   root = NULL;

}

//Functions: copy constructure, calls copyTree to copy a binary search tree

//Pre: Original tree is declared

//Post: copy is created of original tree

void BinarySearchTree::operator= (const BinarySearchTree &originalTree)

{

   //Ignore assigning tre to self

   if (&originalTree == this)

       return;

       //deallocate any existing tree nodes

       Destroy(root);

   //call to CopyTree passing root and originalTree.root

   copyTree(root, originalTree.root);

}

//Functions: isEmpty, determines whether tree is empty

//Pre: Tree has been declared

//Post: Returns true if tree is empty, false otherwise

bool BinarySearchTree::isEmpty()const

{

   //if root is NULL, equations returns true

   return root == NULL;

}

//Functions: IsFull, determines whether a tree is full

//Pre: Tree has been declared

//Post: returns true if there is no longer exists enough memory for a new code

bool BinarySearchTree::isFull()const

{

   //declare a TreeNode pointer

   TreeNode *nodePtr;

       //Try to allocate a ne TreeNode. Exception is thrown if memory doe snot exists

       //for a new node

       try

   {

       nodePtr = new TreeNode;           //exception thrown based on this statement

       delete nodePtr;                   //will not execute if exception thrown

       return false;                   //will not execute if exception thrown

   }

   catch (bad_alloc exception)

   {

       return true;                   //execeutes is exception is caught

   }

}

//Functions: getLength, determines the number of elements in tree. calls the

//           countNodes helper functions

//Pre: Tree has been declared

//Post: Returns the number of element in tree

int BinarySearchTree::getLength() const

{

   //call to countNodes passing the root pointer

   return countNodes(root);

}

void BinarySearchTree::retreiveItem(Criminal &item, bool &found)

{

   //call to retrieve passing root pointer, item and found

   Retrieve(root, item, found);

}

void BinarySearchTree::insertItem(Criminal item)

{

   //call to insert passing root pointer and item

   Insert(root, item);

}

void BinarySearchTree::deleteItem(Criminal item)

{

   //call delete to elete item from tree

   Delete(root, item);

}

void BinarySearchTree::Print(ofstream &outFile) const

{

   //call PrintTree helper function

   printTree(root, outFile);

}

int BinarySearchTree::countNodes(TreeNode *tree) const

{

   if (tree == NULL)

       return 0;           //return 0, if no nodes exist

   else

   {

       //calls countNodes passing left and right child pointers

       return ((countNodes(tree->left) + countNodes(tree->right)) + 1);

   }

}

Criminal BinarySearchTree::getItem(Criminal person, bool& found)

{

   Retrieve(root, person, found);

   return person;

}

void BinarySearchTree::Retrieve(TreeNode *tree, Criminal &item, bool &found)

{

   //search tree using recursive calls

   if (tree == NULL)

       found = false;

   else if (item.getName() < tree->Information.getName())

       Retrieve(tree->left, item, found);

   else if (item.getName() > tree->Information.getName())

       Retrieve(tree->right, item, found);

   else

   {

       //item is found, item is copied

       item = tree->Information;

           found = true;

   }

}

void BinarySearchTree::Insert(TreeNode *&tree, Criminal item)

{

//base case

   if (tree == NULL)

   {

       //declare a new TreeNode

       tree = new TreeNode;

       //set child pointers of new TreeNode to NULL

       tree->right = NULL;

       tree->left = NULL;

       //copy item to node

       tree->Information = item;

}

   else if (item.getName() < tree->Information.getName())

   {

       //recursive call passing TreeNode's left pointer an item

       Insert(tree->left, item);

   }

   else

   {

       //recursive call passing TreeNode's right pointer and item

       Insert(tree->right, item);

}

}

void BinarySearchTree::Delete(TreeNode *&tree, Criminal item)

{

   //use recursion to search for item

   if (item.getName() < tree->Information.getName())

       Delete(tree->left, item);

   else if (item.getName() > tree->Information.getName())

       Delete(tree->right, item);

   else

   {

       //base case - call DeleteNode helper function

       deleteNode(tree);

   }

}

void BinarySearchTree::deleteNode(TreeNode*& tree)

{

   //create a temporary person

   Criminal info;

   //create a temporary pointer

   TreeNode *tempPtr;

   //set tempPtr to tree

   tempPtr = tree;

   //check to see if any of the node's children point to NULL

   if (tree->left == NULL)

   {

       tree = tree->right;

       delete tempPtr;

   }

   else if (tree->right == NULL)

   {

       tree = tree->left;

       delete tempPtr;

   }

   else

   {

       getPredecessor(tree->left, info);

       tree->Information = info;

       Delete(tree->left, info);

   }

}

void BinarySearchTree::getPredecessor(TreeNode*tree, Criminal &item)

{

   //while pointer is not NULL, set tree pointer to right(tree)

   while (tree->right != NULL)

       tree = tree->right;

   //copy information(tree) to info

   item = tree->Information;

}

void BinarySearchTree::printTree(TreeNode *tree, ofstream &outfile) const

{

   //as long as the tree contains elements

   if (tree != NULL)

   {

       //print the left subtree

       printTree(tree->left, outfile);

       //print current node

       Display(tree, outfile);

       //print the right subtree

       printTree(tree->right, outfile);

   }

}

void BinarySearchTree::Destroy(TreeNode *& tree)

{

   //general case

   if (tree != NULL)

   {

       //recursive calls to display subtrees

       Destroy(tree->left);

       Destroy(tree->right);

       delete tree;

   }

}

void BinarySearchTree::copyTree(TreeNode *& copy, const TreeNode *originalTree)

{

   //base case

   if (originalTree == NULL)

   {

       //set copy to NULL

       copy = NULL;

   }

   else

   {

       //general case

       copy = new TreeNode;

       copy->Information = originalTree->Information;

           copyTree(copy->left, originalTree->left);

           copyTree(copy->right, originalTree->right);

}

}

Criminal BinarySearchTree::getNextItem()

{

   Criminal rtn;

   criminalStack.get(rtn);

   return rtn;

}

void BinarySearchTree::fillStack()

{

   fillStackHelper(root);

}

void BinarySearchTree::fillStackHelper(TreeNode* current)

{

   if (current != NULL)

   {

       fillStackHelper(current->left);

       criminalStack.push(current->information);

       fillStackHelper(current->right);

   }

}

BinarySearchTree.h

#ifndef BINARYSEARCHTREE_H

#define BINARYSEARCHTREE_H

#include "Criminal.h"

#include <iostream>

using namespace std;

//Enumerated values used for tree traversal

enum OrderType {PRE_ORDER, IN_ORDER, POST_ORDER};

class BinarySearchTree

{

   //private member variables

private:

   //tree node structure

   struct TreeNode

   {

       Criminal Information;           //holds criminal data

       TreeNode *left;                   //pointer to a tree node's left child

       TreeNode *right;               //pointer to a tree node's right child

   };

   TreeNode *root;                       //pointer to the root node

   //queus needed for PreOrder, PostOrder, and Inordder Traversals

   //QueType preQue;

   //QueType postQue;

   //QueType inQue;

   //helper function prototype

   int countNodes(TreeNode *) const;               //called by Getlength

   void Retrieve(TreeNode*, Criminal &, bool &);   //called by RetrieveItem

   void Insert(TreeNode *&, Criminal);               //called by insert Item

   void Delete(TreeNode *&,Criminal);               //called by delete Item

   void deleteNode(TreeNode *&);                   //called by delete

   void getPredecessor(TreeNode *, Criminal &);   //called by deleteNode

   void printTree(TreeNode *, ofstream &) const;   //called by print

   void Destroy(TreeNode *&);                       //called by destructure

   void Display(TreeNode *, ofstream &) const;       //called by PrintTree

   void copyTree(TreeNode *&, const TreeNode *);   //called by copy constructor

                                                   //and overloaded =.

   void fillStackHelper(TreeNode*);

   //Auxiliary functions for tree traversal

   //called by ResetTree and GetNextItem

   //void PreOrder(TreeNode *);

   //void InOrder(TreeNode *);

   //void PostOrder(TreeNode *);

//Public member functions

public:

   BinarySearchTree();           //constructor

   ~BinarySearchTree();       //destructor

   //copy operations

   BinarySearchTree(const BinarySearchTree &);

   void operator=(const BinarySearchTree &);

   //accessor oprations

   bool isEmpty()const;

   bool isFull()const;

   int getLength() const;

   //Mutator operations

   void makeEmpty();

   void retreiveItem(Criminal &, bool &);

   void insertItem(Criminal);

   void deleteItem(Criminal);

   //void resetTree(OrderType);

   Criminal getItem(Criminal, bool&);

   void Print(ofstream &) const;

   Criminal getNextItem();

   void fillStack();

};

#endif

Criminal.cpp

#include "Criminal.h"

#include <iostream>

#include <string>

using namespace std;

//Person constructor

Criminal::Criminal()

{

   //initialize member variables

   name = "";

}

Criminal::~Criminal()

{

}

//FUNCTION: setName, sets the name variable

void Criminal::setName(string n)

{

   name = n;

}

string Criminal::getName()const

{

   return name;

}

void Criminal::echo(Criminal *ptr)

{

   setName(ptr->getName());

       attributes = ptr->attributes;

}

Criminal.h

#pragma once

#ifndef CRIMINAL_H

#define CRIMINAL_H

#include <string>

#include "LinkedList.h"

using namespace std;

class Criminal

{

   //Private member variables

private:

       string name;

      

public:

   LinkedList <string> attributes;

   Criminal();   //constructor

   //mutators

   void setName(string n);

   void echo(Criminal*);

   //accessors

   string getName() const;

};

#endif

LinkedList.h

//A class template for holding a linked list

#ifndef LINKEDLIST_H

#define LINKEDLIST_H

#include <iostream>

using namespace std;

template <class T>

class LinkedList

{

private:

   //declare a structure for the list.

   struct ListNode

   {

       T value;               //the value in this node

       struct ListNode *next;   //To point to the next node

   };

   ListNode *head;               //List head pointer

public:

   //constructor

   LinkedList()

  

   {

       head = NULL;

   }

   ~LinkedList();

//Linked List Operations

   void appendNode(T);

   void insertNode(T);

   void deleteNode(T);

   void displayList() const;

   int searchList(T) const;

   T getNextItem();

};

/********* constructor ***********/

//template <class T>

//LinkedList<T>::LinkedList()

//{

//   head = nullptr;

   //currentPos = head;

//}

/********* append ***********/

template <class T>

void LinkedList<T>::appendNode(T num)

{

   ListNode *newNode;           //to point to a new node

   ListNode *nodePtr;           //To move through the list

  

   //Allocate a new node and store num there

   newNode = new ListNode;

   newNode->value = num;

   newNode->next = NULL;

   //if there are no nodes in the list

   //make newNode the first node

   if (!head)

       head = newNode;

   else //otherwise, insert newNode at end

   {

       //Initialize nodePtr to head of list

       nodePtr = head;

       //Find the last node in the list.

       while (nodePtr->next)

           nodePtr = nodePtr->next;

       //Insert newNode as the last node.

       nodePtr->next = newNode;

   }

}

/********* insert ***********/

template <class T>

void LinkedList<T>::insertNode(T num)

{

   ListNode *newNode;                   //A new node

   ListNode *nodePtr;                   //To traverse th list

   ListNode *previousNode = NULL;   //The previous node

   //Allocate a new node and store num there.

   newNode = new ListNode;

   newNode->value = num;

   //If there are no nodes in the list

   //make newNode the first node.

   if (!head)

   {

       head = newNode;

       newNode->next = NULL;

   }

   else //Otherwise, insert newNode

   {

       //Position nodePtr at the head of list

       nodePtr = head;

       //Initialize previousNode to NULL

       previousNode = NULL;

       //Skip all nodes whose value is less than num.

       while (nodePtr != nullptr && nodePtr->value < num)

       {

           previousNode = nodePtr;

           nodePtr = nodePtr->next;

       }

       //If the new node is to be the list in the list,

       //insert it before all other nodes.

       if (previousNode == nullptr)

       {

           head = newNode;

           newNode->next = nodePtr;

       }

       else //Otherwise insert after the previous node.

       {

           previousNode->next = newNode;

           newNode->next = nodePtr;

       }

   }

}

/********* delete ***********/

template <class T>

void LinkedList<T>::deleteNode(T num)

{

   ListNode *nodePtr;                   //To traverse the list

   ListNode *previousNode = nullptr;   //To point the previous node

   //If the list is empty, do nothing.

   if (!head)

       return;

  

   //Determine if the first node is the one

   if (head->value == num)

   {

       nodePtr = head->next;

       delete head;

       head = nodePtr;

   }

   else

   {

       //Initialixze nodePtr to head of list

       nodePtr = head;

       //Skip all nodes whose value member is

       //not equal to num

       while (nodePtr != NULL && nodePtr->value != num)

       {

           previousNode = nodePtr;

           nodePtr = nodePtr->next;

       }

       //If nodePtr is not at the end of the list,

       //link the previous node to the node after

       //nodePtr, then delete nodePtr.

       if (nodePtr)

       {

           previousNode->next = nodePtr->next;

           delete nodePtr;

       }

   }

}

/********* display ***********/

template <class T>

void LinkedList<T>::displayList() const

{

   ListNode *nodePtr;               //To move through the list

   nodePtr = head;                   //Position nodePtr at the head of the list.

   //While nodePtr point to a node, traverse the list

   while (nodePtr)

   {

       //Display the value in this node

       cout << nodePtr->value << endl;

       //Move to the next node

       nodePtr = nodePtr->next;

   }

  

}

template <Class T>

LinkedList <T>::~LinkedList()

{

   ListNode *nodePtr;

   ListNode *nextNode;

   nodePtr = head;

   while (nodePtr != NULL)

   {

       nextNode = nodePtr->next;

       delete nodePtr;

       nodePtr = nextNode;

   }

}

/********* search ***********/

template <class T>

int LinkedList<T>::searchList(T num) const

{

   int index = 0;

   ListNode *nodePtr;

   nodePtr = head;

   while (nodePtr)

   {

       if (nodePtr->value == num)

           return index;

       else

       {

           nodePtr = nodePtr->next;

           index++;

       }

   }

   index = -1;

   return index;

}

template <class T>

T LinkedList<T>::getNextItem()

{

   string done = "#";

   if (currentPos == NULL)

       currentPos = head;

   else

       currentPos = currentPos->next;

   if (currentPos != NULL)

       return currentPos->value;

   else

       return done;

  

};

#endif

Main.cpp

#include "Criminal.h"

#include "BinarySearchTree.h"

#include <fstream>

#include <iostream>

#include <string>

#include <cstring>

using namespace std;

//create a ifstream object for input

ifstream input;

//create a ofstream object for output

ofstream output;

//Declare enumerator variables

enum CommandType {ADD, INQUIRY, TIP, CHECK, PRINT, QUIT};

//Global variables

const int MAX_STRINGS = 20;

//Global declarations of list objects for use by all functions

BinarySearchTree suspects;

BinarySearchTree presentCriminals;

string code;

//Declare function prototypes

void criminalList(fstream &);

void listToFile(fstream &);

void add();

void inquiry();

void tip();

void check();

void print();

void addNewSuspect();

void getCommand(CommandType &);

int findMatch(Criminal &);

void getUserInput(Criminal &);

//Begin the main function of the program

int main()

{

   //Open test files

   input.open("Criminal.mf");

   output.open("Criminal.trn");

   //create a file stream object

   fstream mainFile;

   //Enumerator variable

   CommandType command;

   //Add "Criminal.mf" data to lists

   criminalListFile(mainFile);

   //Read first run command

   getCommand(command);

   //Read and process commands until user quits

   while (command != QUIT)

   {

       switch (command)

       {

       case ADD: add();

           break;

       case INQUIRY: inquiry();

           break;

       case QUIT: break;

       }

       getCommand (command);

   }

  

   //write revised lists to "criminal.mf"

   //listToFile(mainFile);

   //close test files

   input.close();

   output.close();

   system("pause");

   return 0;

}

void displayMenu()

{

  

   output << " Enter your choice of command";

   output << "1: ADD: Adds a Suspect to the Suspects data structure. " << endl;

   output << "2: INQUIRY: Enter Name of the INQUIRY. " << endl;

   output << "3: QUIT: Terminate the Program. " << endl;

   output << " ENTER CHOICE: ";

  

}

void getCommand(CommandType &command)

{

   //call function to display menu

   displayMenu();

   int choice;

       //read choice entered by user

       input >> choice;

       bool ok = false;

       while (!ok)

       {

           ok = true;

           switch (choice)

           {

           case 1: command = ADD;

               break;

           case 2: command = INQUIRY;

               break;

           case 3: command = QUIT;

               break;

           default: output << "Error! Enter choice 1, 2, or 3." << endl;

               output << "Reenter" << endl;

               input >> choice;

               ok = false;

               break;

           }

       }

}

void inquiry()

{

   output << "Enter your choice of INQUIRY";

   output << "1: TIP: For TIP information. " << endl;

   output << "2: CHECK: CHECK active suspects. " << endl;

   output << "3: PRINT: PRINT set of active suspects. " << endl;

   output << " ENTER CHOICE: ";

  

}

void inquiryCommand(CommandType &command)

{

   //call functions to display menu

   inquiry();

   int choice;

   //read choice entered by user

   input >> choice;

   bool ok = false;

   while (!ok)

   {

       ok = true;

       switch (choice)

       {

       case 1: command = TIP;

           break;

       case 2: command = CHECK;

           break;

       case 3: command = PRINT;

           break;

       default: output << "Number should be either 1, 2, or 3." << endl;

           output << "Reenter" << endl;

           input >> choice;

           ok = false;

               break;

       }

   }

}

void criminalListFile(fstream &fileIn)

{

   string str;

   fstream criminalList;

   //open criminal "criminal.mf" for reading

   fileIn.open("Criminal.mf", std::ofstream::in);

   if (fileIn.fail())

   {

       output << "Main file did not open" << endl;

   }

   if (criminalList)

   {

       do

       {

           Criminal *newSuspect = new Criminal();

           getline(criminalList, str, ',');

           newSuspect->setName(str);

           getline(criminalList, str, ' ');

           getline(criminalList, str, ',');

           while (str != "#")

           {

               newSuspect->attributes.appendNode(str);

               getline(criminalList, str, ' ');

               getline(criminalList, str, ',');

           }

           newSuspect->attributes.appendNode(str);

           Criminal addPerson;

           addPerson.echo(newSuspect);

           suspects.insertItem(addPerson);

           getline(criminalList, str, ' ');

       } while (!criminalList.eof());

   }

   criminalList.close();

}

void add()

{

   //declare local variables

   bool found;

       // create new suspect

       Criminal *suspect = new Criminal();

   string newSuspect;

   // get suspects name

   cout << "Write New Suspect's Name: ";

   cin >> newSuspect;

   suspect->setName(newSuspect);

   // get suspects attributes

   cout << "What are the attributes of NEW CRIMINAL? ";

   cout << "When you are done press 1" <<endl;

   do

   {

       cout << "- ";

       cin >> newSuspect;

       if (newSuspect != "1")

           suspect->attributes.appendNode(newSuspect);

   } while (newSuspect != "1");

   // add suspect to list

   Criminal addMore;

   addMore.echo(suspect);

   suspects.insertItem(addMore);

   addNewSuspect(addMore);

   cout << " ";

}

void tip()

{

   Criminal checkPerson;

   // get tip info

   string tip, suspectTip = "";

   cout << " Enter the tip info: ";

   cin >> tip;

   presentCriminals.fillStack();

   // get first person in stack

   checkPerson = presentCriminals.getNextItem();

   // while next person is not "null"

   bool match = false;

   while (checkPerson.getName() != "")

   {

       // while there is no match and not at the end of the attribute list

       while (!match && suspectTip != "#")

       {

           suspectTip = checkPerson.attributes.getNextItem();

           if (matches(suspectTip, tip))

               match = true;

       }

       if (!match)

           presentCriminals.deleteItem(checkPerson);

       // check next person, reset suspectTip and match

       checkPerson = presentCriminals.getNextItem();

       suspectTip = "";

       match = false;

   }

   if (presentCriminals.getLength() > 1)

       inquiryCommand();

   else if (presentCriminals.getLength() == 1)

   {

       presentCriminals.fillStack();

       cout << code << " Case has been solved. ";

       cout << "The only suspect left is " << presentCriminals.getNextItem().getName();

       cout << " Book 'Em Danno ";

   }

   else

   {

       cout << "There are no suspects that match all given tips. ";

   }

}

void check()

{

   string str;

   bool found = false;

   cout << " Enter name: ";

   cin >>str;

   presentCriminals.getItem(str, found);

   cout << " ";

   if (!found)

       cout << str << " is not a suspect for this case. ";

   else

       cout << str << " is still a suspect. ";

   inquiryCommand();

}

void print()

{

   Criminal person;

   presentCriminals.fillStack();

   person = presentCriminals.getNextItem();

   cout << " " << code << " Current Suspects: ";

   while (person.getName() != "")

   {

       cout << " " << person.getName() << " ";

       person = presentCriminals.getNextItem();

   }

   cout << " ";

   inquiryCommand();

}

bool matches(const string& a, const string& b)

{

   unsigned int s = a.size();

   if (b.size() != s)

       return false;

   for (unsigned int i = 0; i < s; ++i)

       if (tolower(a[i]) != tolower(b[i]))

           return false;

   return true;

}

Stack.h

#pragma once

#ifndef STACK_H

#define STACK_H

#include <iostream>

using namespace std;

template <class T>

class Stack

{

private:

   struct StackNode

   {

       T value;

       StackNode *next;

   };

   StackNode *top;

public:

   Stack();

   ~Stack();

   void push(T);

   bool pop(T &);

   bool get(T &);

   bool isEmpty();

};

/************** constructor ***************/

template <class T>

Stack<T>::Stack()

{

   top = nullptr;

}

/************** destructor ***************/

template <class T>

Stack<T>::~Stack()

{

   StackNode *nodePtr,

       *nextNode;

   nodePtr = top;

   while (nodePtr != nullptr)

   {

       nextNode = nodePtr->next;

       delete nodePtr;

       nodePtr = nextNode;

   }

}

/************** push ***************/

template <class T>

void Stack<T>::push(T item)

{

   StackNode *newNode = nullptr;

   newNode = new StackNode;

   newNode->value = item;

   if (isEmpty())

   {

       top = newNode;

       newNode->next = nullptr;

   }

   else

   {

       newNode->next = top;

       top = newNode;

   }

}

/************** pop ***************/

template <class T>

bool Stack<T>::pop(T &item)

{

   bool status;

   StackNode *temp = nullptr;

   if (isEmpty())

       status = false;

   else

   {

       item = top->value;

       temp = top->next;

       delete top;

       top = temp;

       status = true;

   }

   return status;

}

template <class T>

bool Stack<T>::get(T &item)

{

   bool status;

   StackNode *temp = nullptr;

   if (isEmpty())

       status = false;

   else

   {

       item = top->value;

       temp = top->next;

       top = temp;

       status = true;

   }

   return status;

}

/************** is empty ***************/

template <class T>

bool Stack<T>::isEmpty()

{

   bool status;

   if (!top)

       status = true;

   else

       status = false;

   return status;

}

#endif

Also, instead of LinkedList and Stack, if you could use Recursion with BinarySearch, that would be even better.

Command

Processing

ADD

Add a suspect to the Suspects data structure. Prompt the user for the suspect's name and a list of attributes. ADD commands can be issued only before an inquiry begins.

INQUIRY

Prompt user for code name of this inquiry. Once the inquiry has begun, do not allow the user to issue the ADD command until this inquiry is complete.

TIP

Prompt user for the tip information (a particular attribute). Process the tip, reducing the set of current suspects by deleting suspects who do not match the attribute mentioned in the tip. If there is only one suspect left in the set of active suspects, print out a message indicating that the crime is solved. Be sure to include the suspect's name and inquiry code name. This terminates the current inquiry.

CHECK

Prompt the user for a suspect's name. Check the set of active suspects to see if this name is there; print out an appropriate response.

PRINT

Print the set of active suspects (those who have not yet been eliminated).

QUIT

If any new suspects have been added during this execution of the program, rewrite the "Criminal.mf" file. Be careful about how you go about saving the records; the traversal order affects the shape of the tree that is built on the next execution of the program. Terminate the program.

Explanation / Answer

BinarySearchTree.cpp

#include "BinarySearchTree.h"

#include <iostream>

#include <fstream>

using namespace std;

//Begin BinarySearchTree Class Functions Definitions

//Functions: Constructor, sets root to null

//Pre: None

//Post: Root is Null

BinarySearchTree::BinarySearchTree()

{

   //set root to NULL

   root = NULL;

}

//Functions: Destructor, deletes a binary search Tree

//Pre: None

//Post: Tree is deleted

BinarySearchTree::~BinarySearchTree()

{

   //calls Destroy passing root of binary search tree

   Destroy(root);

}

//Funcions: MakeEmpty, removes all the nodes from the tree

//Pre: None

//Post: Nodes are deleted, root is set to NULL

void BinarySearchTree::makeEmpty()

{

   //calls Destroy passing root of binary search tree

   Destroy(root);

   //Set root to null

   root = NULL;

}

//Functions: copy constructure, calls copyTree to copy a binary search tree

//Pre: Original tree is declared

//Post: copy is created of original tree

void BinarySearchTree::operator= (const BinarySearchTree &originalTree)

{

   //Ignore assigning tre to self

   if (&originalTree == this)

       return;

       //deallocate any existing tree nodes

       Destroy(root);

   //call to CopyTree passing root and originalTree.root

   copyTree(root, originalTree.root);

}

//Functions: isEmpty, determines whether tree is empty

//Pre: Tree has been declared

//Post: Returns true if tree is empty, false otherwise

bool BinarySearchTree::isEmpty()const

{

   //if root is NULL, equations returns true

   return root == NULL;

}

//Functions: IsFull, determines whether a tree is full

//Pre: Tree has been declared

//Post: returns true if there is no longer exists enough memory for a new code

bool BinarySearchTree::isFull()const

{

   //declare a TreeNode pointer

   TreeNode *nodePtr;

       //Try to allocate a ne TreeNode. Exception is thrown if memory doe snot exists

       //for a new node

       try

   {

       nodePtr = new TreeNode;           //exception thrown based on this statement

       delete nodePtr;                   //will not execute if exception thrown

       return false;                   //will not execute if exception thrown

   }

   catch (bad_alloc exception)

   {

       return true;                   //execeutes is exception is caught

   }

}

//Functions: getLength, determines the number of elements in tree. calls the

//           countNodes helper functions

//Pre: Tree has been declared

//Post: Returns the number of element in tree

int BinarySearchTree::getLength() const

{

   //call to countNodes passing the root pointer

   return countNodes(root);

}

void BinarySearchTree::retreiveItem(Criminal &item, bool &found)

{

   //call to retrieve passing root pointer, item and found

   Retrieve(root, item, found);

}

void BinarySearchTree::insertItem(Criminal item)

{

   //call to insert passing root pointer and item

   Insert(root, item);

}

void BinarySearchTree::deleteItem(Criminal item)

{

   //call delete to elete item from tree

   Delete(root, item);

}

void BinarySearchTree::Print(ofstream &outFile) const

{

   //call PrintTree helper function

   printTree(root, outFile);

}

int BinarySearchTree::countNodes(TreeNode *tree) const

{

   if (tree == NULL)

       return 0;           //return 0, if no nodes exist

   else

   {

       //calls countNodes passing left and right child pointers

       return ((countNodes(tree->left) + countNodes(tree->right)) + 1);

   }

}

Criminal BinarySearchTree::getItem(Criminal person, bool& found)

{

   Retrieve(root, person, found);

   return person;

}

void BinarySearchTree::Retrieve(TreeNode *tree, Criminal &item, bool &found)

{

   //search tree using recursive calls

   if (tree == NULL)

       found = false;

   else if (item.getName() < tree->Information.getName())

       Retrieve(tree->left, item, found);

   else if (item.getName() > tree->Information.getName())

       Retrieve(tree->right, item, found);

   else

   {

       //item is found, item is copied

       item = tree->Information;

           found = true;

   }

}

void BinarySearchTree::Insert(TreeNode *&tree, Criminal item)

{

//base case

   if (tree == NULL)

   {

       //declare a new TreeNode

       tree = new TreeNode;

       //set child pointers of new TreeNode to NULL

       tree->right = NULL;

       tree->left = NULL;

       //copy item to node

       tree->Information = item;

}

   else if (item.getName() < tree->Information.getName())

   {

       //recursive call passing TreeNode's left pointer an item

       Insert(tree->left, item);

   }

   else

   {

       //recursive call passing TreeNode's right pointer and item

       Insert(tree->right, item);

}

}

void BinarySearchTree::Delete(TreeNode *&tree, Criminal item)

{

   //use recursion to search for item

   if (item.getName() < tree->Information.getName())

       Delete(tree->left, item);

   else if (item.getName() > tree->Information.getName())

       Delete(tree->right, item);

   else

   {

       //base case - call DeleteNode helper function

       deleteNode(tree);

   }

}

void BinarySearchTree::deleteNode(TreeNode*& tree)

{

   //create a temporary person

   Criminal info;

   //create a temporary pointer

   TreeNode *tempPtr;

   //set tempPtr to tree

   tempPtr = tree;

   //check to see if any of the node's children point to NULL

   if (tree->left == NULL)

   {

       tree = tree->right;

       delete tempPtr;

   }

   else if (tree->right == NULL)

   {

       tree = tree->left;

       delete tempPtr;

   }

   else

   {

       getPredecessor(tree->left, info);

       tree->Information = info;

       Delete(tree->left, info);

   }

}

void BinarySearchTree::getPredecessor(TreeNode*tree, Criminal &item)

{

   //while pointer is not NULL, set tree pointer to right(tree)

   while (tree->right != NULL)

       tree = tree->right;

   //copy information(tree) to info

   item = tree->Information;

}

void BinarySearchTree::printTree(TreeNode *tree, ofstream &outfile) const

{

   //as long as the tree contains elements

   if (tree != NULL)

   {

       //print the left subtree

       printTree(tree->left, outfile);

       //print current node

       Display(tree, outfile);

       //print the right subtree

       printTree(tree->right, outfile);

   }

}

void BinarySearchTree::Destroy(TreeNode *& tree)

{

   //general case

   if (tree != NULL)

   {

       //recursive calls to display subtrees

       Destroy(tree->left);

       Destroy(tree->right);

       delete tree;

   }

}

void BinarySearchTree::copyTree(TreeNode *& copy, const TreeNode *originalTree)

{

   //base case

   if (originalTree == NULL)

   {

       //set copy to NULL

       copy = NULL;

   }

   else

   {

       //general case

       copy = new TreeNode;

       copy->Information = originalTree->Information;

           copyTree(copy->left, originalTree->left);

           copyTree(copy->right, originalTree->right);

}

}

Criminal BinarySearchTree::getNextItem()

{

   Criminal rtn;

   criminalStack.get(rtn);

   return rtn;

}

void BinarySearchTree::fillStack()

{

   fillStackHelper(root);

}

void BinarySearchTree::fillStackHelper(TreeNode* current)

{

   if (current != NULL)

   {

       fillStackHelper(current->left);

       criminalStack.push(current->information);

       fillStackHelper(current->right);

   }

}

BinarySearchTree.h

#ifndef BINARYSEARCHTREE_H

#define BINARYSEARCHTREE_H

#include "Criminal.h"

#include <iostream>

using namespace std;

//Enumerated values used for tree traversal

enum OrderType {PRE_ORDER, IN_ORDER, POST_ORDER};

class BinarySearchTree

{

   //private member variables

private:

   //tree node structure

   struct TreeNode

   {

       Criminal Information;           //holds criminal data

       TreeNode *left;                   //pointer to a tree node's left child

       TreeNode *right;               //pointer to a tree node's right child

   };

   TreeNode *root;                       //pointer to the root node

   //queus needed for PreOrder, PostOrder, and Inordder Traversals

   //QueType preQue;

   //QueType postQue;

   //QueType inQue;

   //helper function prototype

   int countNodes(TreeNode *) const;               //called by Getlength

   void Retrieve(TreeNode*, Criminal &, bool &);   //called by RetrieveItem

   void Insert(TreeNode *&, Criminal);               //called by insert Item

   void Delete(TreeNode *&,Criminal);               //called by delete Item

   void deleteNode(TreeNode *&);                   //called by delete

   void getPredecessor(TreeNode *, Criminal &);   //called by deleteNode

   void printTree(TreeNode *, ofstream &) const;   //called by print

   void Destroy(TreeNode *&);                       //called by destructure

   void Display(TreeNode *, ofstream &) const;       //called by PrintTree

   void copyTree(TreeNode *&, const TreeNode *);   //called by copy constructor

                                                   //and overloaded =.

   void fillStackHelper(TreeNode*);

   //Auxiliary functions for tree traversal

   //called by ResetTree and GetNextItem

   //void PreOrder(TreeNode *);

   //void InOrder(TreeNode *);

   //void PostOrder(TreeNode *);

//Public member functions

public:

   BinarySearchTree();           //constructor

   ~BinarySearchTree();       //destructor

   //copy operations

   BinarySearchTree(const BinarySearchTree &);

   void operator=(const BinarySearchTree &);

   //accessor oprations

   bool isEmpty()const;

   bool isFull()const;

   int getLength() const;

   //Mutator operations

   void makeEmpty();

   void retreiveItem(Criminal &, bool &);

   void insertItem(Criminal);

   void deleteItem(Criminal);

   //void resetTree(OrderType);

   Criminal getItem(Criminal, bool&);

   void Print(ofstream &) const;

   Criminal getNextItem();

   void fillStack();

};

#endif

Criminal.cpp

#include "Criminal.h"

#include <iostream>

#include <string>

using namespace std;

//Person constructor

Criminal::Criminal()

{

   //initialize member variables

   name = "";

}

Criminal::~Criminal()

{

}

//FUNCTION: setName, sets the name variable

void Criminal::setName(string n)

{

   name = n;

}

string Criminal::getName()const

{

   return name;

}

void Criminal::echo(Criminal *ptr)

{

   setName(ptr->getName());

       attributes = ptr->attributes;

}

Criminal.h

#pragma once

#ifndef CRIMINAL_H

#define CRIMINAL_H

#include <string>

#include "LinkedList.h"

using namespace std;

class Criminal

{

   //Private member variables

private:

       string name;

      

public:

   LinkedList <string> attributes;

   Criminal();   //constructor

   //mutators

   void setName(string n);

   void echo(Criminal*);

   //accessors

   string getName() const;

};

#endif

LinkedList.h

//A class template for holding a linked list

#ifndef LINKEDLIST_H

#define LINKEDLIST_H

#include <iostream>

using namespace std;

template <class T>

class LinkedList

{

private:

   //declare a structure for the list.

   struct ListNode

   {

       T value;               //the value in this node

       struct ListNode *next;   //To point to the next node

   };

   ListNode *head;               //List head pointer

public:

   //constructor

   LinkedList()

  

   {

       head = NULL;

   }

   ~LinkedList();

//Linked List Operations

   void appendNode(T);

   void insertNode(T);

   void deleteNode(T);

   void displayList() const;

   int searchList(T) const;

   T getNextItem();

};

/********* constructor ***********/

//template <class T>

//LinkedList<T>::LinkedList()

//{

//   head = nullptr;

   //currentPos = head;

//}

/********* append ***********/

template <class T>

void LinkedList<T>::appendNode(T num)

{

   ListNode *newNode;           //to point to a new node

   ListNode *nodePtr;           //To move through the list

  

   //Allocate a new node and store num there

   newNode = new ListNode;

   newNode->value = num;

   newNode->next = NULL;

   //if there are no nodes in the list

   //make newNode the first node

   if (!head)

       head = newNode;

   else //otherwise, insert newNode at end

   {

       //Initialize nodePtr to head of list

       nodePtr = head;

       //Find the last node in the list.

       while (nodePtr->next)

           nodePtr = nodePtr->next;

       //Insert newNode as the last node.

       nodePtr->next = newNode;

   }

}

/********* insert ***********/

template <class T>

void LinkedList<T>::insertNode(T num)

{

   ListNode *newNode;                   //A new node

   ListNode *nodePtr;                   //To traverse th list

   ListNode *previousNode = NULL;   //The previous node

   //Allocate a new node and store num there.

   newNode = new ListNode;

   newNode->value = num;

   //If there are no nodes in the list

   //make newNode the first node.

   if (!head)

   {

       head = newNode;

       newNode->next = NULL;

   }

   else //Otherwise, insert newNode

   {

       //Position nodePtr at the head of list

       nodePtr = head;

       //Initialize previousNode to NULL

       previousNode = NULL;

       //Skip all nodes whose value is less than num.

       while (nodePtr != nullptr && nodePtr->value < num)

       {

           previousNode = nodePtr;

           nodePtr = nodePtr->next;

       }

       //If the new node is to be the list in the list,

       //insert it before all other nodes.

       if (previousNode == nullptr)

       {

           head = newNode;

           newNode->next = nodePtr;

       }

       else //Otherwise insert after the previous node.

       {

           previousNode->next = newNode;

           newNode->next = nodePtr;

       }

   }

}

/********* delete ***********/

template <class T>

void LinkedList<T>::deleteNode(T num)

{

   ListNode *nodePtr;                   //To traverse the list

   ListNode *previousNode = nullptr;   //To point the previous node

   //If the list is empty, do nothing.

   if (!head)

       return;

  

   //Determine if the first node is the one

   if (head->value == num)

   {

       nodePtr = head->next;

       delete head;

       head = nodePtr;

   }

   else

   {

       //Initialixze nodePtr to head of list

       nodePtr = head;

       //Skip all nodes whose value member is

       //not equal to num

       while (nodePtr != NULL && nodePtr->value != num)

       {

           previousNode = nodePtr;

           nodePtr = nodePtr->next;

       }

       //If nodePtr is not at the end of the list,

       //link the previous node to the node after

       //nodePtr, then delete nodePtr.

       if (nodePtr)

       {

           previousNode->next = nodePtr->next;

           delete nodePtr;

       }

   }

}

/********* display ***********/

template <class T>

void LinkedList<T>::displayList() const

{

   ListNode *nodePtr;               //To move through the list

   nodePtr = head;                   //Position nodePtr at the head of the list.

   //While nodePtr point to a node, traverse the list

   while (nodePtr)

   {

       //Display the value in this node

       cout << nodePtr->value << endl;

       //Move to the next node

       nodePtr = nodePtr->next;

   }

  

}

template <Class T>

LinkedList <T>::~LinkedList()

{

   ListNode *nodePtr;

   ListNode *nextNode;

   nodePtr = head;

   while (nodePtr != NULL)

   {

       nextNode = nodePtr->next;

       delete nodePtr;

       nodePtr = nextNode;

   }

}

/********* search ***********/

template <class T>

int LinkedList<T>::searchList(T num) const

{

   int index = 0;

   ListNode *nodePtr;

   nodePtr = head;

   while (nodePtr)

   {

       if (nodePtr->value == num)

           return index;

       else

       {

           nodePtr = nodePtr->next;

           index++;

       }

   }

   index = -1;

   return index;

}

template <class T>

T LinkedList<T>::getNextItem()

{

   string done = "#";

   if (currentPos == NULL)

       currentPos = head;

   else

       currentPos = currentPos->next;

   if (currentPos != NULL)

       return currentPos->value;

   else

       return done;

  

};

#endif

Main.cpp

#include "Criminal.h"

#include "BinarySearchTree.h"

#include <fstream>

#include <iostream>

#include <string>

#include <cstring>

using namespace std;

//create a ifstream object for input

ifstream input;

//create a ofstream object for output

ofstream output;

//Declare enumerator variables

enum CommandType {ADD, INQUIRY, TIP, CHECK, PRINT, QUIT};

//Global variables

const int MAX_STRINGS = 20;

//Global declarations of list objects for use by all functions

BinarySearchTree suspects;

BinarySearchTree presentCriminals;

string code;

//Declare function prototypes

void criminalList(fstream &);

void listToFile(fstream &);

void add();

void inquiry();

void tip();

void check();

void print();

void addNewSuspect();

void getCommand(CommandType &);

int findMatch(Criminal &);

void getUserInput(Criminal &);

//Begin the main function of the program

int main()

{

   //Open test files

   input.open("Criminal.mf");

   output.open("Criminal.trn");

   //create a file stream object

   fstream mainFile;

   //Enumerator variable

   CommandType command;

   //Add "Criminal.mf" data to lists

   criminalListFile(mainFile);

   //Read first run command

   getCommand(command);

   //Read and process commands until user quits

   while (command != QUIT)

   {

       switch (command)

       {

       case ADD: add();

           break;

       case INQUIRY: inquiry();

           break;

       case QUIT: break;

       }

       getCommand (command);

   }

  

   //write revised lists to "criminal.mf"

   //listToFile(mainFile);

   //close test files

   input.close();

   output.close();

   system("pause");

   return 0;

}

void displayMenu()

{

  

   output << " Enter your choice of command";

   output << "1: ADD: Adds a Suspect to the Suspects data structure. " << endl;

   output << "2: INQUIRY: Enter Name of the INQUIRY. " << endl;

   output << "3: QUIT: Terminate the Program. " << endl;

   output << " ENTER CHOICE: ";

  

}

void getCommand(CommandType &command)

{

   //call function to display menu

   displayMenu();

   int choice;

       //read choice entered by user

       input >> choice;

       bool ok = false;

       while (!ok)

       {

           ok = true;

           switch (choice)

           {

           case 1: command = ADD;

               break;

           case 2: command = INQUIRY;

               break;

           case 3: command = QUIT;

               break;

           default: output << "Error! Enter choice 1, 2, or 3." << endl;

               output << "Reenter" << endl;

               input >> choice;

               ok = false;

               break;

           }

       }

}

void inquiry()

{

   output << "Enter your choice of INQUIRY";

   output << "1: TIP: For TIP information. " << endl;

   output << "2: CHECK: CHECK active suspects. " << endl;

   output << "3: PRINT: PRINT set of active suspects. " << endl;

   output << " ENTER CHOICE: ";

  

}

void inquiryCommand(CommandType &command)

{

   //call functions to display menu

   inquiry();

   int choice;

   //read choice entered by user

   input >> choice;

   bool ok = false;

   while (!ok)

   {

       ok = true;

       switch (choice)

       {

       case 1: command = TIP;

           break;

       case 2: command = CHECK;

           break;

       case 3: command = PRINT;

           break;

       default: output << "Number should be either 1, 2, or 3." << endl;

           output << "Reenter" << endl;

           input >> choice;

           ok = false;

               break;

       }

   }

}

void criminalListFile(fstream &fileIn)

{

   string str;

   fstream criminalList;

   //open criminal "criminal.mf" for reading

   fileIn.open("Criminal.mf", std::ofstream::in);

   if (fileIn.fail())

   {

       output << "Main file did not open" << endl;

   }

   if (criminalList)

   {

       do

       {

           Criminal *newSuspect = new Criminal();

           getline(criminalList, str, ',');

           newSuspect->setName(str);

           getline(criminalList, str, ' ');

           getline(criminalList, str, ',');

           while (str != "#")

           {

               newSuspect->attributes.appendNode(str);

               getline(criminalList, str, ' ');

               getline(criminalList, str, ',');

           }

           newSuspect->attributes.appendNode(str);

           Criminal addPerson;

           addPerson.echo(newSuspect);

           suspects.insertItem(addPerson);

           getline(criminalList, str, ' ');

       } while (!criminalList.eof());

   }

   criminalList.close();

}

void add()

{

   //declare local variables

   bool found;

       // create new suspect

       Criminal *suspect = new Criminal();

   string newSuspect;

   // get suspects name

   cout << "Write New Suspect's Name: ";

   cin >> newSuspect;

   suspect->setName(newSuspect);

   // get suspects attributes

   cout << "What are the attributes of NEW CRIMINAL? ";

   cout << "When you are done press 1" <<endl;

   do

   {

       cout << "- ";

       cin >> newSuspect;

       if (newSuspect != "1")

           suspect->attributes.appendNode(newSuspect);

   } while (newSuspect != "1");

   // add suspect to list

   Criminal addMore;

   addMore.echo(suspect);

   suspects.insertItem(addMore);

   addNewSuspect(addMore);

   cout << " ";

}

void tip()

{

   Criminal checkPerson;

   // get tip info

   string tip, suspectTip = "";

   cout << " Enter the tip info: ";

   cin >> tip;

   presentCriminals.fillStack();

   // get first person in stack

   checkPerson = presentCriminals.getNextItem();

   // while next person is not "null"

   bool match = false;

   while (checkPerson.getName() != "")

   {

       // while there is no match and not at the end of the attribute list

       while (!match && suspectTip != "#")

       {

           suspectTip = checkPerson.attributes.getNextItem();

           if (matches(suspectTip, tip))

               match = true;

       }

       if (!match)

           presentCriminals.deleteItem(checkPerson);

       // check next person, reset suspectTip and match

       checkPerson = presentCriminals.getNextItem();

       suspectTip = "";

       match = false;

   }

   if (presentCriminals.getLength() > 1)

       inquiryCommand();

   else if (presentCriminals.getLength() == 1)

   {

       presentCriminals.fillStack();

       cout << code << " Case has been solved. ";

       cout << "The only suspect left is " << presentCriminals.getNextItem().getName();

       cout << " Book 'Em Danno ";

   }

   else

   {

       cout << "There are no suspects that match all given tips. ";

   }

}

void check()

{

   string str;

   bool found = false;

   cout << " Enter name: ";

   cin >>str;

   presentCriminals.getItem(str, found);

   cout << " ";

   if (!found)

       cout << str << " is not a suspect for this case. ";

   else

       cout << str << " is still a suspect. ";

   inquiryCommand();

}

void print()

{

   Criminal person;

   presentCriminals.fillStack();

   person = presentCriminals.getNextItem();

   cout << " " << code << " Current Suspects: ";

   while (person.getName() != "")

   {

       cout << " " << person.getName() << " ";

       person = presentCriminals.getNextItem();

   }

   cout << " ";

   inquiryCommand();

}

bool matches(const string& a, const string& b)

{

   unsigned int s = a.size();

   if (b.size() != s)

       return false;

   for (unsigned int i = 0; i < s; ++i)

       if (tolower(a[i]) != tolower(b[i]))

           return false;

   return true;

}

Stack.h

#pragma once

#ifndef STACK_H

#define STACK_H

#include <iostream>

using namespace std;

template <class T>

class Stack

{

private:

   struct StackNode

   {

       T value;

       StackNode *next;

   };

   StackNode *top;

public:

   Stack();

   ~Stack();

   void push(T);

   bool pop(T &);

   bool get(T &);

   bool isEmpty();

};

/************** constructor ***************/

template <class T>

Stack<T>::Stack()

{

   top = nullptr;

}

/************** destructor ***************/

template <class T>

Stack<T>::~Stack()

{

   StackNode *nodePtr,

       *nextNode;

   nodePtr = top;

   while (nodePtr != nullptr)

   {

       nextNode = nodePtr->next;

       delete nodePtr;

       nodePtr = nextNode;

   }

}

/************** push ***************/

template <class T>

void Stack<T>::push(T item)

{

   StackNode *newNode = nullptr;

   newNode = new StackNode;

   newNode->value = item;

   if (isEmpty())

   {

       top = newNode;

       newNode->next = nullptr;

   }

   else

   {

       newNode->next = top;

       top = newNode;

   }

}

/************** pop ***************/

template <class T>

bool Stack<T>::pop(T &item)

{

   bool status;

   StackNode *temp = nullptr;

   if (isEmpty())

       status = false;

   else

   {

       item = top->value;

       temp = top->next;

       delete top;

       top = temp;

       status = true;

   }

   return status;

}

template <class T>

bool Stack<T>::get(T &item)

{

   bool status;

   StackNode *temp = nullptr;

   if (isEmpty())

       status = false;

   else

   {

       item = top->value;

       temp = top->next;

       top = temp;

       status = true;

   }

   return status;

}

/************** is empty ***************/

template <class T>

bool Stack<T>::isEmpty()

{

   bool status;

   if (!top)

       status = true;

   else

       status = false;

   return status;

}

#endif

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote