LinkedBag.h
#ifndef _LINKED_BAG
#define _LINKED_BAG
#include "BagInterface.h"
#include "Node.h"
template<class ItemType>
class LinkedBag : public BagInterface<ItemType>
{
private:
Node<ItemType>* headPtr; // Pointer to first node
int itemCount; // Current count of bag items
// Fills the vector bagContents with the data in the nodes of
// the linked chain to which curPtr points.
void fillVector(vector<ItemType>& bagContents, Node<ItemType>* curPtr) const;
// Locates a given entry within this bag.
// Returns either a pointer to the node containing a given entry or
// the null pointer if the entry is not in the bag.
Node<ItemType>* getPointerTo(const ItemType& target,
Node<ItemType>* curPtr) const;
// Counts the frequency of occurrence of a given entry in this bag.
int countFrequency(const ItemType& anEntry, int counter,
Node<ItemType>* curPtr) const;
// Deallocates all nodes assigned to this bag
void deallocate(Node<ItemType>* nextNodePtr);
public:
LinkedBag();
LinkedBag(const LinkedBag<ItemType>& aBag); // Copy constructor
virtual ~LinkedBag(); // Destructor should be virtual
int getCurrentSize() const;
bool isEmpty() const;
bool add(const ItemType& newEntry);
bool remove(const ItemType& anEntry);
void clear();
bool contains(const ItemType& anEntry) const;
int getFrequencyOf(const ItemType& anEntry) const;
vector<ItemType> toVector() const;
}; // end LinkedBag
#include "LinkedBag.cpp"
#endif
Node.cpp
#include "Node.h"
#include <cstddef>
template<class ItemType>
Node<ItemType>::Node() : next(nullptr)
{
} // end default constructor
template<class ItemType>
Node<ItemType>::Node(const ItemType& anItem) : item(anItem), next(nullptr)
{
} // end constructor
template<class ItemType>
Node<ItemType>::Node(const ItemType& anItem, Node<ItemType>* nextNodePtr) :
item(anItem), next(nextNodePtr)
{
} // end constructor
template<class ItemType>
void Node<ItemType>::setItem(const ItemType& anItem)
{
item = anItem;
} // end setItem
template<class ItemType>
void Node<ItemType>::setNext(Node<ItemType>* nextNodePtr)
{
next = nextNodePtr;
} // end setNext
template<class ItemType>
ItemType Node<ItemType>::getItem() const
{
return item;
} // end getItem
template<class ItemType>
Node<ItemType>* Node<ItemType>::getNext() const
{
return next;
} // end getNext
BagInterface.h
#ifndef _BAG_INTERFACE
#define _BAG_INTERFACE
#include <vector>
using namespace std;
template<class ItemType>
class BagInterface
{
public:
/** Gets the current number of entries in this bag.
@return The integer number of entries currently in the bag. */
virtual int getCurrentSize() const = 0;
/** Sees whether this bag is empty.
@return True if the bag is empty, or false if not. */
virtual bool isEmpty() const = 0;
/** Adds a new entry to this bag.
@post If successful, newEntry is stored in the bag and
the count of items in the bag has increased by 1.
@param newEntry The object to be added as a new entry.
@return True if addition was successful, or false if not. */
virtual bool add(const ItemType& newEntry) = 0;
/** Removes one occurrence of a given entry from this bag,
if possible.
@post If successful, anEntry has been removed from the bag
and the count of items in the bag has decreased by 1.
@param anEntry The entry to be removed.
@return True if removal was successful, or false if not. */
virtual bool remove(const ItemType& anEntry) = 0;
/** Removes all entries from this bag.
@post Bag contains no items, and the count of items is 0. */
virtual void clear() = 0;
/** Counts the number of times a given entry appears in bag.
@param anEntry The entry to be counted.
@return The number of times anEntry appears in the bag. */
virtual int getFrequencyOf(const ItemType& anEntry) const = 0;
/** Tests whether this bag contains a given entry.
@param anEntry The entry to locate.
@return True if bag contains anEntry, or false otherwise. */
virtual bool contains(const ItemType& anEntry) const = 0;
/** Empties and then f ills a given vector with all entries that
are in this bag.
@return A vector containing all the entries in the bag. */
virtual vector<ItemType> toVector() const = 0;
}; // end BagInterface
#endif
Node.h
#ifndef _NODE
#define _NODE
template<class ItemType>
class Node
{
private:
ItemType item; // A data item
Node<ItemType>* next; // Pointer to next node
public:
Node();
Node(const ItemType& anItem);
Node(const ItemType& anItem, Node<ItemType>* nextNodePtr);
void setItem(const ItemType& anItem);
void setNext(Node<ItemType>* nextNodePtr);
ItemType getItem() const ;
Node<ItemType>* getNext() const ;
}; // end Node
//#include "Node.cpp"
#endif
LinkedBag.cpp
#include "LinkedBag.h"
#include "Node.h"
#include <cstddef>
template<class ItemType>
LinkedBag<ItemType>::LinkedBag() : headPtr(nullptr), itemCount(0)
{
} // end default constructor
template<class ItemType>
LinkedBag<ItemType>::LinkedBag(const LinkedBag<ItemType>& aBag)
{
itemCount = aBag.itemCount;
Node<ItemType>* origChainPtr = aBag.headPtr; // Points to nodes in original chain
if (origChainPtr == nullptr)
headPtr = nullptr; // Original bag is empty
else
{
// Copy first node
headPtr = new Node<ItemType>();
headPtr->setItem(origChainPtr->getItem());
// Copy remaining nodes
Node<ItemType>* newChainPtr = headPtr; // Points to last node in new chain
origChainPtr = origChainPtr->getNext(); // Advance original-chain pointer
while (origChainPtr != nullptr)
{
// Get next item from original chain
ItemType nextItem = origChainPtr->getItem();
origChainPtr = origChainPtr->getNext(); // Advance original-chain pointer
// Create a new node containing the next item
Node<ItemType>* newNodePtr = new Node<ItemType>(nextItem);
// Link new node to end of new chain
newChainPtr->setNext(newNodePtr);
// Advance pointer to new last node
newChainPtr = newChainPtr->getNext();
} // end while
newChainPtr->setNext(nullptr); // Flag end of chain
} // end if
} // end copy constructor
template<class ItemType>
LinkedBag<ItemType>::~LinkedBag()
{
clear();
} // end destructor
template<class ItemType>
bool LinkedBag<ItemType>::isEmpty() const
{
return itemCount == 0;
} // end isEmpty
template<class ItemType>
int LinkedBag<ItemType>::getCurrentSize() const
{
return itemCount;
} // end getCurrentSize
template<class ItemType>
bool LinkedBag<ItemType>::add(const ItemType& newEntry)
{
// Add to beginning of chain: new node references rest of chain;
// (headPtr is null if chain is empty)
Node<ItemType>* nextNodePtr = new Node<ItemType>();
nextNodePtr->setItem(newEntry);
nextNodePtr->setNext(headPtr); // New node points to chain
// Node<ItemType>* nextNodePtr = new Node<ItemType>(newEntry, headPtr); // alternate code
headPtr = nextNodePtr; // New node is now first node
itemCount++;
return true;
} // end add
template<class ItemType>
vector<ItemType> LinkedBag<ItemType>::toVector() const
{
vector<ItemType> bagContents;
fillVector(bagContents, headPtr);
return bagContents;
} // end toVector
template<class ItemType>
bool LinkedBag<ItemType>::remove(const ItemType& anEntry)
{
Node<ItemType>* entryNodePtr = getPointerTo(anEntry, headPtr);
bool canRemoveItem = !isEmpty() && (entryNodePtr != nullptr);
if (canRemoveItem)
{
// Copy data from first node to located node
entryNodePtr->setItem(headPtr->getItem());
// Delete first node
Node<ItemType>* nodeToDeletePtr = headPtr;
headPtr = headPtr->getNext();
// Return node to the system
nodeToDeletePtr->setNext(nullptr);
delete nodeToDeletePtr;
nodeToDeletePtr = nullptr;
itemCount--;
} // end if
return canRemoveItem;
} // end remove
template<class ItemType>
void LinkedBag<ItemType>::clear()
{
deallocate(headPtr);
headPtr = nullptr;
itemCount = 0;
} // end clear
template<class ItemType>
int LinkedBag<ItemType>::getFrequencyOf(const ItemType& anEntry) const
{
return countFrequency(anEntry, 0, headPtr);
} // end getFrequencyOf
template<class ItemType>
bool LinkedBag<ItemType>::contains(const ItemType& anEntry) const
{
return (getPointerTo(anEntry, headPtr) != nullptr);
} // end contains
/* ALTERNATE 1
template<class ItemType>
bool LinkedBag<ItemType>::contains(const ItemType& anEntry) const
{
return getFrequencyOf(anEntry) > 0;
}
*/
/* ALTERNATE 2
template<class ItemType>
bool LinkedBag<ItemType>::contains(const ItemType& anEntry) const
{
bool found = false;
Node<ItemType>* curPtr = headPtr;
int i = 0;
while (!found && (curPtr != nullptr) && (i < itemCount))
{
if (anEntry == curPtr-<getItem())
{
found = true;
}
else
{
i++;
curPtr = curPtr->getNext();
} // end if
} // end while
return found;
} // end contains
*/
// Private Methods:
template<class ItemType>
void LinkedBag<ItemType>::fillVector(vector<ItemType>& bagContents,
Node<ItemType>* curPtr) const
{
if (curPtr != nullptr)
{
bagContents.push_back(curPtr->getItem());
fillVector(bagContents, curPtr->getNext());
} // end if
} // end toVector
template<class ItemType>
Node<ItemType>* LinkedBag<ItemType>::getPointerTo(const ItemType& target,
Node<ItemType>* curPtr) const
{
Node<ItemType>* result = nullptr;
if (curPtr != nullptr)
{
if (target== curPtr->getItem())
result = curPtr;
else
result = getPointerTo(target, curPtr->getNext());
} // end if
return result;
} // end getPointerTo
template<class ItemType>
int LinkedBag<ItemType>::countFrequency(const ItemType& anEntry, int counter,
Node<ItemType>* curPtr) const
{
int frequency = 0;
if ((curPtr != nullptr) && (counter < itemCount))
{
if (anEntry == curPtr->getItem())
{
frequency = 1 + countFrequency(anEntry, counter + 1, curPtr->getNext());
}
else
{
frequency = countFrequency(anEntry, counter + 1, curPtr->getNext());
} // end if
} // end while
return frequency;
} // end countFrequency
template<class ItemType>
void LinkedBag<ItemType>::deallocate(Node<ItemType>* nextNodePtr)
{
Node<ItemType>* nodeToDeletePtr = nextNodePtr;
if (nextNodePtr != nullptr)
{
nextNodePtr = nextNodePtr->getNext();
delete nodeToDeletePtr;
nodeToDeletePtr = nextNodePtr;
deallocate(nextNodePtr);
} // end if
} // end deallocate
main.cpp
#include <iostream>
#include <string>
#include "LinkedBag.h"
using namespace std;
void displayBag(LinkedBag<string>& bag)
{
cout << "The bag contains " << bag.getCurrentSize()
<< " items:" << endl;
vector<string> bagItems = bag.toVector();
int numberOfEntries = (int) bagItems.size();
for (int i = 0; i < numberOfEntries; i++)
{
cout << bagItems[i] << " ";
} // end for
cout << endl << endl;
} // end displayBag
void bagTester(LinkedBag<string>& bag)
{
cout << "isEmpty: returns " << bag.isEmpty()
<< "; should be 1 (true)" << endl;
displayBag(bag);
string items[] = {"one", "two", "three", "four", "five", "one"};
cout << "Add 6 items to the bag: " << endl;
for (int i = 0; i < 6; i++)
{
bag.add(items[i]);
} // end for
displayBag(bag);
cout << "isEmpty: returns " << bag.isEmpty()
<< "; should be 0 (false)" << endl;
cout << "getCurrentSize: returns " << bag.getCurrentSize()
<< "; should be 6" << endl;
cout << "Try to add another entry: add(\"extra\") returns "
<< bag.add("extra") << endl;
cout << "contains(\"three\"): returns " << bag.contains("three")
<< "; should be 1 (true)" << endl;
cout << "contains(\"ten\"): returns " << bag.contains("ten")
<< "; should be 0 (false)" << endl;
cout << "getFrequencyOf(\"one\"): returns "
<< bag.getFrequencyOf("one") << " should be 2" << endl;
cout << "remove(\"one\"): returns " << bag.remove("one")
<< "; should be 1 (true)" << endl;
cout << "getFrequencyOf(\"one\"): returns "
<< bag.getFrequencyOf("one") << " should be 1" << endl;
cout << "remove(\"one\"): returns " << bag.remove("one")
<< "; should be 1 (true)" << endl;
cout << "remove(\"one\"): returns " << bag.remove("one")
<< "; should be 0 (false)" << endl;
cout << endl;
displayBag(bag);
cout << "After clearing the bag, ";
bag.clear();
cout << "isEmpty: returns " << bag.isEmpty()
<< "; should be 1 (true)" << endl;
} // end bagTester
int main()
{
LinkedBag<string> bag;
cout << "Testing the Link-Based Bag:" << endl;
cout << "The initial bag is empty." << endl;
bagTester(bag);
cout << "All done!" << endl;
return 0;
} // end main
15 Errors in Visual Studio
Severity Code Description Project File Line Suppression State Error C2995 'int LinkedBag::getCurrentSize(void) const': function template has already been defined LinkedBagRecursive c:\users\jun\documents\data structures\linkedbagrecursive\linkedbag.cpp 65
Error C2995 'LinkedBag::LinkedBag(void)': function template has already been defined LinkedBagRecursive c:\users\jun\documents\data structures\linkedbagrecursive\linkedbag.cpp 8
Error C2995 'LinkedBag::LinkedBag(const LinkedBag &)': function template has already been defined LinkedBagRecursive c:\users\jun\documents\data structures\linkedbagrecursive\linkedbag.cpp 47
Error C2995 'LinkedBag::~LinkedBag(void)': function template has already been defined LinkedBagRecursive c:\users\jun\documents\data structures\linkedbagrecursive\linkedbag.cpp 53
Error C2995 'bool LinkedBag::isEmpty(void) const': function template has already been defined LinkedBagRecursive c:\users\jun\documents\data structures\linkedbagrecursive\linkedbag.cpp 59
Error C2995 'bool LinkedBag::add(const ItemType &)': function template has already been defined LinkedBagRecursive c:\users\jun\documents\data structures\linkedbagrecursive\linkedbag.cpp 81
Error C2995 'std::vector> LinkedBag::toVector(void) const': function template has already been defined LinkedBagRecursive c:\users\jun\documents\data structures\linkedbagrecursive\linkedbag.cpp 89
Error C2995 'bool LinkedBag::remove(const ItemType &)': function template has already been defined LinkedBagRecursive c:\users\jun\documents\data structures\linkedbagrecursive\linkedbag.cpp 114 Error C2995 'void LinkedBag::clear(void)': function template has already been defined LinkedBagRecursive c:\users\jun\documents\data structures\linkedbagrecursive\linkedbag.cpp 122 Error C2995 'int LinkedBag::getFrequencyOf(const ItemType &) const': function template has already been defined LinkedBagRecursive c:\users\jun\documents\data structures\linkedbagrecursive\linkedbag.cpp 128 Error C2995 'bool LinkedBag::contains(const ItemType &) const': function template has already been defined LinkedBagRecursive c:\users\jun\documents\data structures\linkedbagrecursive\linkedbag.cpp 134 Error C2995 'void LinkedBag::fillVector(std::vector> &,Node *) const': function template has already been defined LinkedBagRecursive c:\users\jun\documents\data structures\linkedbagrecursive\linkedbag.cpp 178 Error C2995 'Node *LinkedBag::getPointerTo(const ItemType &,Node *) const': function template has already been defined LinkedBagRecursive c:\users\jun\documents\data structures\linkedbagrecursive\linkedbag.cpp 194 Error C2995 'int LinkedBag::countFrequency(const ItemType &,int,Node *) const': function template has already been defined LinkedBagRecursive c:\users\jun\documents\data structures\linkedbagrecursive\linkedbag.cpp 214 Error C2995 'void LinkedBag::deallocate(Node *)': function template has already been defined LinkedBagRecursive c:\users\jun\documents\data structures\linkedbagrecursive\linkedbag.cpp 227
Aucun commentaire:
Enregistrer un commentaire