Tuesday, July 14, 2009

Need help creating c++ set class?

I'm creating a new class for c++ based on Set theory. I was given Set.h and have to create Set.cpp. I need help with the cardinality function. I'm uncertain how to do it. Here is the program:





#include %26lt;iostream%26gt;


#include "Set.h"





// Constructor, sets _cardinality to zero


Set::Set(){


_cardinality=0;


}





// returns true if its argument is an element of the set


bool Set::isElement(const int num) const{


for(int i=0; i%26lt;_cardinality; i++){


if(_element[i]==num){


return true;


}


else{


return false;


}


}


}





// adds the argument to the set


void Set::add( int num){


for(int i=0; i%26lt; _cardinality; i++){


if(_element[i]==num){


return;


}


else{


_element[_cardinality]=num;


_cardinality++;


i++;


}


}


}





// removes the element from the set


void Set::remove(int num){


for(int i=0; i%26lt; _cardinality; i++){


if(_element[i]!=num){


return;


}


else if(_cardinality==1){


clear();


}


else{


_element[i]=_element[i+1];


_cardinality--;


}


}


}





// resets cardinality to zero (effectively emptying the set)


void Set::clear(){


for(int i=0; i%26lt;_cardinality-1; i++){


_element[i]=0;


}


}





// returns the cardinality of the set


unsigned int Set::cardinality()const {


int count=0;


count=


return count;


}





// prints out the contents of the set to the terminal, all elements,


// comma separated list, no line breaks


void Set::print() const {


for(int i=0; i%26lt; _cardinality; i++){


cout %26lt;%26lt; _element[i] %26lt;%26lt;", ";


}


cout %26lt;%26lt; endl;





}





// returns a set object representing the intersection


// of its two arguments


Set operator*( const Set%26amp; a, const Set%26amp; b)


{


int n=0;


Set rv;


for( int i = 0; i %26lt; a.cardinality(); i++ ){


for(int j=0; j%26lt; b.cardinality(); j++){


if(a._element[i]==b._element[j]){


rv._element[n]=a._element[i];


n++;


}


}


}


rv.print();


}





// returns a set object representing the union


// of its two arguments


Set operator+( const Set%26amp; a, const Set%26amp; b)


{


Set u, x;


int sz_u=0, sz_x=0, sz_d=0;


//compute union


for(int i=0; i%26lt;sz_u; ++i) {


u._element[i] = a._element[i];


++sz_u;


}


int sz_u_old = sz_u;


for(int i=0; i%26lt;sz_x; ++i) {


bool found=false;


for(int j=0; j%26lt;sz_u_old; ++j) {


if (b._element[i] == u._element[j]) {


found = true;


break;


}


}


if (!found) {


u._element[sz_u] = b._element[i];


++sz_u;


}


}


for(int i=0; i%26lt;sz_u; ++i) {


cout %26lt;%26lt; u._element[i] %26lt;%26lt; ", ";


}


cout %26lt;%26lt; endl;


}





// prints out the contents of the set to the terminal, all elements,


// comma separated list, no line breaks


ostream%26amp; operator%26lt;%26lt;(ostream%26amp; output, const Set%26amp; a){


for(int i=0; i%26lt;a.cardinality(); i++){


output %26lt;%26lt; a._element[i] %26lt;%26lt; ", ";


}


}





// adds second argument to the set in the first argument


void operator+=(Set%26amp; a, const int rhs){


Set num;


for(int i=0; i%26lt;a.cardinality(); i++){


num._element[i]=a._element[i]+rhs;


}


num.print();


}





// removes second argument from the set in the first argument, returns


// true if an element was actually removed, otherwise returns false


bool operator-=(Set%26amp; a, const int rhs)


{


Set num;


for(int i=0; i%26lt;a.cardinality(); i++){


num._element[i]=a._element[i]-rhs;


if(num._element[i]==0){


num.remove(num._element[i]);


return true;


}


else{


return false;


}


}


num.print();


}





// returns true if the left side is a subset of the right


bool operator%26lt;(const Set%26amp; rhs, const Set%26amp; num)


{


for(int i=0; i%26lt;num.cardinality(); i++){


for(int j=0; j%26lt;num.cardinality(); j++){


if(num.isElement(rhs._element[j])==true)...


return true;


}


else{


return false;


}


}


}


}





// returns true if the left side is an element of the right


bool operator%26lt;(const int%26amp; rhs, const Set%26amp; num)


{


for(int i=0; i%26lt;num.cardinality(); i++){


if(num.isElement(rhs)==true){


return true;


}


else{


return false;


}


}


}





// returns true if the right side is a subset of the left


bool operator%26gt;(const Set%26amp; rhs, const Set%26amp; num)


{


for(int i=0; i%26lt;rhs.cardinality(); i++){


for(int j=0; j%26lt;num.cardinality(); j++){


if(rhs.isElement(num._element[j])==true)...


return true;


}


else{


return false;


}


}


}


}





// returns true if the right side is an element of the left


bool operator%26gt;(const Set%26amp; num, const int%26amp; rhs)


{


for(int i=0; i%26lt;num.cardinality(); i++){


if(num.isElement(rhs)==true){


return true;


}


else{


return false;


}


}


}

Need help creating c++ set class?
If the add( ) operation increments _cardinality, and your remove( ) operation decrements _cardinality and packs the element array, and clear() sets _cardinality to zero, all the cardinality( ) operation needs to do is return the value of the _cardinality attribute.





It looks like you're trying to pack the array in remove( ), but I don't think your logic there is right. E.g., if the first element in the set is not the one to be removed, you return? You need to test that function and make sure it works.





Your add( ) operation increments the loop counter in the 'for' statement and also inside the loop, which looks suspicious. I think add( ) can be as simple as this:





if (isElement(num) == false) {


element[_cardinality++] = num;


}





remove( ) should also use isElement( ) to determine if the specified value is in the set. In fact, it would be convenient for remove( ) if isElement( ) were to return the index of the requested value, if present in the set, or -1 if not. Then, if the value is found, remove( ) can start at the returned index, and pack the array from there.





I assume the Set class definition you were given declared the elements attribute as a simple array of int. Does it have a fixed, max size? If so, you need to be careful in add( ) not to exceed the bounds of element[ ]. It would be nice if element was a vector%26lt;int%26gt;. If not, it should be an int*, dynamically allocated to some initial, max size, with the size possibly provided to a Constructor. Then if any of your operations need a bigger element array, you can reallocate. Perhaps to simplify this assignment, the Set definition you were given just declared element[ ] to be a fixed size. In that case, add( ) would just have to reject a request to add past the bounds of the array.





You have a really good start on the implementation of this class. Clean up your logic a bit, and do some thorough testing, and I'm sure it'll turn out well.


No comments:

Post a Comment