In: Computer Science
C++ Class involving Set intersection
The goal is to overload the function:
void Bag::operator/=(const Bag& a_bag)
// Bag<int> bag1 = 1,2,3,4
//Bag<int> bag2 = 2,5,6,7
bag1+=bag2;
bag1.display() should return 2
//Since type is void, you should not be returning any array but change the bag itself.
#include <iostream> #include <string> #include <vector> using namespace std; template<class T> class Bag { public: Bag(); int getCurrentSize() const; bool isEmpty() const; bool add(const T& new_entry); bool remove(const T& an_entry); /** @post item_count_ == 0 **/ void clear(); /** @return true if an_etry is found in items_, false otherwise **/ bool contains(const T& an_entry) const; /** @return the number of times an_entry is found in items_ **/ int getFrequencyOf(const T& an_entry) const; /** @return a vector having the same cotntents as items_ **/ std::vector<T> toVector() const; void display() const; // displays the output void operator/=(const Bag<T>& a_bag); //DO NOT CHANGE RETURN TYPE protected: static const int DEFAULT_CAPACITY = 200; //max size of items_ T items_[DEFAULT_CAPACITY]; // Array of bag items int item_count_; // Current count of bag items int getIndexOf(const T& target) const; };
template<class T> Bag<T>::Bag(): item_count_(0) { } // end default constructor template<class T> int Bag<T>::getCurrentSize() const { return item_count_; } // end getCurrentSize template<class T> bool Bag<T>::isEmpty() const { return item_count_ == 0; } // end isEmpty template<class T> bool Bag<T>::add(const T& new_entry) { bool has_room = (item_count_ < DEFAULT_CAPACITY); //bool notDup = items_.getFrequencyOf(new_entry) == 0; if (has_room) //&& notDup) { items_[item_count_] = new_entry; item_count_++; return true; } // end if return false; } // end add template<class T> void Bag<T>::display() const { for(int x = 0; x < item_count_;x++) cout << items_[x] << ", "; } /** @return true if an_etry was successfully removed from items_, false otherwise **/ template<class T> bool Bag<T>::remove(const T& an_entry) { int found_index = getIndexOf(an_entry); bool can_remove = !isEmpty() && (found_index > -1); if (can_remove) { item_count_--; items_[found_index] = items_[item_count_]; } // end if return can_remove; } // end remove /** @post item_count_ == 0 **/ template<class T> void Bag<T>::clear() { item_count_ = 0; } // end clear template<class T> int Bag<T>::getFrequencyOf(const T& an_entry) const { int frequency = 0; int cun_index = 0; // Current array index while (cun_index < item_count_) { if (items_[cun_index] == an_entry) { frequency++; } // end if cun_index++; // Increment to next entry } // end while return frequency; } // end getFrequencyOf template<class T> bool Bag<T>::contains(const T& an_entry) const { return getIndexOf(an_entry) > -1; } // end contains template<class T> std::vector<T> Bag<T>::toVector() const { std::vector<T> bag_contents; for (int i = 0; i < item_count_; i++) bag_contents.push_back(items_[i]); return bag_contents; } // end toVector
template<class T> void Bag<T>::operator/=(const Bag<T>& a_bag)
{}
I've added the code below with comments wherever required. I've bold the parts which have been changed. Explanation below the code! Note: the function getIndexOf was missing from the code, I've implemented that as well :)
.......................................................................CODE START...........................................................................
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
using namespace std;
template<class T>
class Bag
{
public:
Bag();
int getCurrentSize() const;
bool isEmpty() const;
bool add(const T& new_entry);
bool remove(const T& an_entry);
/**
@post item_count_ == 0
**/
void clear();
/**
@return true if an_etry is found in items_,
false otherwise
**/
bool contains(const T& an_entry) const;
/**
@return the number of times an_entry is
found in items_
**/
int getFrequencyOf(const T& an_entry)
const;
/**
@return a vector having the same cotntents
as items_
**/
std::vector<T> toVector() const;
void display() const; // displays the output
void operator/=(const Bag<T>& a_bag); //DO NOT CHANGE RETURN TYPE
protected:
static const int DEFAULT_CAPACITY = 200; //max
size of items_
T
items_[DEFAULT_CAPACITY];
// Array of bag items
int
item_count_;
// Current count of bag items
int getIndexOf(const T& target) const;
};
template<class T>
Bag<T>::Bag(): item_count_(0)
{
} // end default constructor
template<class T>
int Bag<T>::getCurrentSize() const
{
return item_count_;
} // end getCurrentSize
template<class T>
bool Bag<T>::isEmpty() const
{
return item_count_ == 0;
} // end isEmpty
template<class T>
bool Bag<T>::add(const T& new_entry)
{
bool has_room = (item_count_ <
DEFAULT_CAPACITY);
//bool notDup = items_.getFrequencyOf(new_entry)
== 0;
if (has_room) //&& notDup)
{
items_[item_count_] =
new_entry;
item_count_++;
return true;
} // end if
return false;
} // end add
template<class T>
void Bag<T>::display() const
{
for(int x = 0; x < item_count_; x++)
cout << items_[x]
<< ", ";
}
template<class T>
int Bag<T>::getIndexOf(const T& entry) const
{
T const *ed = items_ + item_count_; // End of
the items_ array
int const *result = std::find(items_, ed,
entry); // Find the index of the element within the boundaries of
the items_ array
if (result != ed) // If found, ...
{
return
std::distance(items_, result); // Return the distance of the
iterator result from the start of the array (index i)
}
return -1; // Else, return -1
}
/**
@return true if an_etry was successfully removed from items_, false
otherwise
**/
template<class T>
bool Bag<T>::remove(const T& an_entry)
{
int found_index = getIndexOf(an_entry);
bool can_remove = !isEmpty() &&
(found_index > -1);
if (can_remove)
{
item_count_--;
items_[found_index] =
items_[item_count_];
} // end if
return can_remove;
} // end remove
/**
@post item_count_ == 0
**/
template<class T>
void Bag<T>::clear()
{
item_count_ = 0;
} // end clear
template<class T>
int Bag<T>::getFrequencyOf(const T& an_entry) const
{
int frequency = 0;
int cun_index =
0; // Current array index
while (cun_index < item_count_)
{
if (items_[cun_index] ==
an_entry)
{
frequency++;
} // end if
cun_index++;
// Increment to next entry
} // end while
return frequency;
} // end getFrequencyOf
template<class T>
bool Bag<T>::contains(const T& an_entry) const
{
return getIndexOf(an_entry) > -1;
} // end contains
template<class T>
std::vector<T> Bag<T>::toVector() const
{
std::vector<T> bag_contents;
for (int i = 0; i < item_count_; i++)
bag_contents.push_back(items_[i]);
return bag_contents;
} // end toVector
template<class T>
void Bag<T>::operator/=(const Bag<T>& a_bag)
{
int i = 0;
while (i < item_count_) // Loop until all
items are not traversed
{
if
(!a_bag.contains(items_[i])) // If bag2 does not contain this
element, remove it from the items_ array
{
remove(items_[i]);
// Don't increment i as the current item has not been seen
}
else
{
i++; // Done looking current element, increment i
}
}
}
int main()
{
Bag<int> bag1;
bag1.add(1);
bag1.add(2);
bag1.add(3);
bag1.add(4);
Bag<int> bag2;
bag2.add(2);
bag2.add(5);
bag2.add(6);
bag2.add(7);
bag1 /= bag2;
bag1.display();
return 0;
}
.......................................................................CODE END...........................................................................
Output:
2
Output is as expected. Let's see what we've done,
We iterate bag1 one-by-one and see if the current element is in bag2,
If it is, it belongs to the intersection, hence do nothing
If it doesn't, it is not a part of the intersection of the sets, hence use the remove function to remove it from bag1.
It's that simple!
Hope this helps!