C++/c++

Advertisement


Question
hello again,

first thanks for pointing me in the right direction on that last program.

i have written another program in which i am almost done with, but it has a few kinks i am stuck on.    thanks for any help you can give.

program background:  

create class IntegerSet where each object can hold integers in range of 0 - 100. a set is represented internally as an array of ones and zeros.  for example, array element a[i] is 1 if integer i is in the set, and arrary element a[j] is 0 if integer j is not in the set.  the default constructor initializes a set to the " empty-set," a set whos array representation contains all zeros.  the only thing im having trouble with for some reason is the void emptySet() function  definition, IntegerSet deleteElement functions() deleteElement member fuction that deletes m by setting set[m] to 0.  the program compiles and you can enter numbers, but im not getting the output desired.

this is a sample of what the Output should look like:
Enter Set A:
Enter an element (-1 to end):45  
Enter an element (-1 to end):76
Enter an element (-1 to end):34
Enter an element (-1 to end):6
Enter an element (-1 to end):-1
Entry Complete

Enter Set B:
Enter an element (-1 to end):34
Enter an element (-1 to end):8
Enter an element (-1 to end):93
Enter an element (-1 to end):45
Enter an element (-1 to end):-1
Entry Complete

Union of A and B is:
{ 6 8 34 45 76 93}

Intersection of A and B is:
{ 6 34 45 76 77}

Inserting 77 into set A
Set A is now:
{6 34 45 76 77}

Deleting 77 from set A
Set A is now: {6 34 45 76}
invalid insert attempted!
invalid insert attempted!

set e is:
{1 2 9 25 67 99 100}

End sample Output

here is my program in 3 files via cut/paste:

//IntegerSet.h
// Header file for class IntegerSet
#ifndef INTEGER_SET_H
#define INTEGER_SET_H

class IntegerSet
{
public:  
  // default constructor
  IntegerSet()
  {
     /* Write call to emptySet */
  } // end IntegerSet constructor

  IntegerSet( int [], int ); // constructor that takes an initial set
  IntegerSet unionOfSets( const IntegerSet& );
  IntegerSet intersectionOfSets (const IntegerSet&);/* Write a member funcion prototype for intersectionOfSets */
  void emptySet(); // set all elements of set to 0
  void inputSet(); // read values from user
  void insertElement( int );
  IntegerSet deleteElement ( const IntegerSet& ); /* Write a member function prototype for deleteElement */
  void printSet();
  bool isEqualTo ( const IntegerSet& ); /* Write a member function prototype for isEqualTo */
private:
  int set[ 101 ]; // range of 0 - 100

  // determines a valid entry to the set
  int validEntry( int x ) const
  {
     return ( x >= 0 && x <= 100 );
  } // end function validEntry
}; // end class IntegerSet

#endif

//IntegerSet.cpp
// Member-function definitions for class IntegerSet.
#include <iostream>
using std::cout;
using std::cin;
using std::cerr;

#include <iomanip>
using std::setw;

#include "IntegerSet.h" /* Write include directive for IntegerSet.h here */

// constructor creates a set from array of integers
IntegerSet::IntegerSet( int intArray[], int size)
{
   for ( int i = 0; i < size; i++ )
     insertElement( intArray[ i ] );
} // end IntegerSet constructor

void emptySet ()
{
  /* Write a definition for emptySet */
}

// input a set from the user
void IntegerSet::inputSet()
{
  int number;

  do
  {
     cout << "Enter an element (-1 to end): ";
     cin >> number;

     if ( validEntry( number ) )
        set[ number ] = 1;
     else if ( number != -1 )
        cerr << "Invalid Element
";
  } while ( number != -1 ); // end do...while

  cout << "Entry complete
";
} // end function inputSet

// prints the set to the output stream
void IntegerSet::printSet()
{
  int x = 1;
  bool empty = true; // assume set is empty
  
  cout << '{';

  for (int u = 0; u < 101; u++ )
  {
     if ( set[ u ] )
     {
        cout << setw( 4 ) << u << ( x % 10 == 0 ? "
" : "" );
        empty = false; // set is not empty
        x++;
     } // end if
  } // end for

  if ( empty )
     cout << setw( 4 ) << "---"; // display an empty set
     
  cout << setw( 4 ) << "}" << '
';
} // end function printSet

// returns the union of two sets
IntegerSet IntegerSet::unionOfSets( const IntegerSet &r )
{
  IntegerSet temp;

  // if element is in either set, add to temporary set
  for ( int n = 0; n < 101; n++ )
     if ( set[ n ] == 1 || r.set[ n ] == 1 )
        temp.set[ n ] = 1;

  return temp;
} // end function unionOfSets

/* Write definition for intersectionOfSets */
IntegerSet IntegerSet::intersectionOfSets( const IntegerSet &r )
{
  IntegerSet temp;

  // if element is in both set, add to temporary set
  for ( int n = 0; n < 101; n++ )
     
  
     if ( set[ n ] == 1 && r.set[ n ] == 1 )
        temp.set[ n ] = 1;

  return temp;
} // end function intersectionOfSets



// insert a new integer into this set
void IntegerSet::insertElement( int k )
{
  if ( validEntry( k ) )
     set[ k ] = 1;
  else
     cerr << "Invalid insert attempted!
";
} // end function insertElement

/* Write definition for deleteElement */
IntegerSet deleteElement ( const IntegerSet& )
{
  set [ m ] = 0;
}
/* Write definition for isEqualTo */
// determines if two sets are equal


bool IntegerSet::isEqualTo( const IntegerSet &r )
{
  for ( int v = 0; v < 101; v++ )
     if ( set[ v ] == r.set[ v ] )
        return true; // sets are not-equal
    else
  return false; // sets are equal
} // end function isEqualTo

//SetTest.cpp
// Driver program for class IntegerSet.
#include <iostream>
using std::cout;
using std::endl;

#include "IntegerSet.h" // IntegerSet class definition

int main()
{
  IntegerSet a;
  IntegerSet b;
  IntegerSet c;
  IntegerSet d;

  cout << "Enter set A:
";
  a.inputSet();
  cout << "
Enter set B:
";
  b.inputSet();
  /* Write call to unionOfSets for object a, passing
     b as argument and assigning the result to c */
  c = a.unionOfSets( b );

  

  /* Write call to intersectionOfSets for object a,
     passing b as argument and assigning the result to d */
  d = a.intersectionOfSets( b );

  cout << "
Union of A and B is:
";
  c.printSet();
  cout << "Intersection of A and B is:
";
  d.printSet();

  if ( a.isEqualTo( b ) )
     cout << "Set A is equal to set B
";
  else
     cout << "Set A is not equal to set B
";

  cout << "
Inserting 77 into set A...
";
  a.insertElement( 77 );
  cout << "Set A is now:
";
  a.printSet();

  cout << "
Deleting 77 from set A...
";
//   a.deleteElement( 77 );
  cout << "Set A is now:
";
  a.printSet();

  const int arraySize = 10;
  int intArray[ arraySize ] = { 25, 67, 2, 9, 99, 105, 45, -5, 100, 1 };
  IntegerSet e( intArray, arraySize );

  cout << "
Set e is:
";
  e.printSet();

  cout << endl;
  system("Pause");
  return 0;
} // end main

Answer
Hi Jwilson.



For emptySet:
==========================
You can assign 0 to every element of set using a for loop
void IntegerSet::emptySet ()
{
   for(i = 0; i < 101; ++i) set[i] = 0;
}
Or, you could use memset instead of the "for" loop to make the memory of set all 0, like this:
void IntegerSet::emptySet ()
{
   memset(set, 0, sizeof(set[0]) * 101);
}

The emptySet method is a member of the IntegerSet, so you specify the definition it by prefixing it with "IntegerSet::" You were missing the prefix.

For deleteElement
=======================================
I suggest that you make deleteElement symmetric with insertElement. Notice that insertElement takes an element and inserts it into the IntegerSet being worked on. The insertElement does not return a new set.
The deleteElement should work in the same way. It should modify the IntegerSet being worked on and not return a new set. So deleteElement should be declared as
void deleteElement ( int );
and defined as
void IntegerSet::deleteElement ( int m)
{
   if (isValidEntry(m)) set[m] = 0;
   else cerr << "Invalid delete attempted!"
}

Default constructor
===============================
Your assignment requires a default constructor which is missing. Remember to put in a default constructor to assign 0 to every element of the set. You can call the emptySet from the constructor to do the actual work.

isEqualTo
=================================
Look closely at your isEqualTo method.
bool IntegerSet::isEqualTo( const IntegerSet &r )
{
   for ( int v = 0; v < 101; v++ )
       if ( set[ v ] == r.set[ v ] )
         return true; // sets are not-equal
       else
         return false; // sets are equal
} // end function isEqualTo
Is it examining all elements in the set? It is examining only the first element, and making a return based on it. You can say that two sets are UNequal as soon as you find one element which does not match, but you cannot say two sets are equal until you examine all elements. You cannot return true until all elements are examined. I will leave it to you to rewrite it.


Final comment
=================================
Notice that it is not a good practice to hard-code magic numbers like 101 throughout your program. If you ever need to change to say 200 elements, you would need to make many changes in your code. If you miss a spot, your program will not work properly. As an exercise, try defining a constant integer for your set size, and go through your program and change all the magic numbers to be in terms of the SetSize. For example, inside your IntegerSet class you can do this:
private:
   static const int SetSize = 101;
   int set[ SetSize ]; // range of 0 - 100

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Zlatko

Expertise

No longer taking questions.

Experience

No longer taking questions.

Education/Credentials
No longer taking questions.

©2016 About.com. All rights reserved.