#include <cstddef>
#include <iostream>
#include <string>
// ------- HEADER ------
class LinkedGroceryList
{
private:
struct Grocery
{
std::string name;
std::size_t quantity;
bool purchased;
Grocery* next;
};
Grocery* head;
std::size_t differentGroceries;
std::size_t totalGroceries;
public:
LinkedGroceryList();
~LinkedGroceryList();
void addGrocery(std::string const&, std::size_t);
void removeGrocery(std::string const&, unsigned int);
bool findGrocery(std::string const&) const;
void markAsPurchased(std::string const&);
void displayGroceries() const;
void clearGroceries();
std::size_t different() const { return differentGroceries; }
std::size_t total() const { return totalGroceries; }
bool empty() const { return differentGroceries == 0; }
};
// ------ IMPLEMENTATION ------
LinkedGroceryList::LinkedGroceryList()
: head(nullptr)
, differentGroceries(0)
, totalGroceries(0)
{}
LinkedGroceryList::~LinkedGroceryList()
{
clearGroceries();
}
void LinkedGroceryList::addGrocery(std::string const& name, std::size_t quantity)
{
Grocery* newGrocery = new Grocery;
newGrocery->name = name;
newGrocery->quantity = quantity;
newGrocery->purchased = false;
newGrocery->next = nullptr;
if (!head)
{
head = newGrocery;
}
else
{
Grocery* groceryPtr = head;
while (groceryPtr->next)
groceryPtr = groceryPtr->next;
groceryPtr->next = newGrocery;
}
differentGroceries++;
totalGroceries += quantity;
}
void LinkedGroceryList::removeGrocery(std::string const& name, unsigned int quantity)
{
if (!head) return;
Grocery* groceryPtr;
if (head->name == name)
{
groceryPtr = head;
head = groceryPtr->next;
totalGroceries -= quantity;
if (quantity == groceryPtr->quantity)
differentGroceries--;
else
{
groceryPtr->quantity -= quantity;
return;
}
delete groceryPtr;
}
else
{
Grocery* predPtr = nullptr;
groceryPtr = head;
while (groceryPtr && groceryPtr->name != name)
{
predPtr = groceryPtr;
groceryPtr = groceryPtr->next;
}
if (groceryPtr)
{
totalGroceries -= quantity;
if (quantity == groceryPtr->quantity)
differentGroceries--;
else
{
groceryPtr->quantity -= quantity;
return;
}
predPtr->next = groceryPtr->next;
delete groceryPtr;
}
}
}
bool LinkedGroceryList::findGrocery(std::string const& name) const
{
if (!head) return false;
if (head->name == name)
return true;
else
{
Grocery* groceryPtr = head->next;
while (groceryPtr)
{
if (groceryPtr->name == name)
return true;
groceryPtr = groceryPtr->next;
}
}
return false;
}
void LinkedGroceryList::markAsPurchased(std::string const& name)
{
Grocery* groceryPtr = head;
while (groceryPtr)
{
if (groceryPtr->name == name)
groceryPtr->purchased = true;
groceryPtr = groceryPtr->next;
}
}
void LinkedGroceryList::displayGroceries() const
{
if (!head) return;
Grocery* groceryPtr = head;
while (groceryPtr)
{
std::cout << groceryPtr->name << ", ";
std::cout << groceryPtr->quantity << ", ";
std::cout << ((groceryPtr->purchased) ? "purchased\n" : "not purchased\n");
groceryPtr = groceryPtr->next;
}
}
void LinkedGroceryList::clearGroceries()
{
if (!head) return;
Grocery* predPtr = head;
Grocery* nextGrocery;
while (predPtr)
{
nextGrocery = predPtr->next;
delete predPtr;
predPtr = nextGrocery;
}
head = nullptr;
differentGroceries = 0;
totalGroceries = 0;
}
// ------ DRIVER ------
int main()
{
LinkedGroceryList meats;
meats.addGrocery("steak", 5);
meats.addGrocery("chicken", 3);
meats.addGrocery("pork", 2);
meats.displayGroceries();
std::cout << "\nDifferent items: " << meats.different() << "\n";
std::cout << "Total items: " << meats.total();
std::cout << "\nsteak present? " << std::boolalpha << meats.findGrocery("steak");
std::cout << "\ncarrots present? " << std::boolalpha << meats.findGrocery("carrots");
std::cout << "\n\nRemoving 1 pork...\n\n";
meats.removeGrocery("pork", 1);
meats.displayGroceries();
std::cout << "\nDifferent items: " << meats.different() << "\n";
std::cout << "Total items: " << meats.total();
std::cout << "\npork present? " << std::boolalpha << meats.findGrocery("pork");
meats.markAsPurchased("steak");
std::cout << "\n\nsteak has been purchased\n\n";
meats.displayGroceries();
}