C++/C++

Advertisement


Question
hello again,


i have written another program in which i am almost done with, but it has a few kinks that 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
I am not going to write the code for you as this would effectively finish your assignment for you. Oh, and looking at the comments I think that maybe you did not have to write all the class and test harness code yourself but only had to fill in certain parts - which is where you have come unstuck (and I suspect hope that someone will do your parts for you!).

However I am going to point you in the right direction.

So starting with you problems with writing the void emptySet() function.

First emptySet is declared to be a public instance member function of the IntegerSet class:

   class IntegerSet
   {
   public:  

   ...

       void emptySet(); // set all elements of set to 0

   ...

However you define a non-member free function (i.e. one that is just a function and not a class member) in the implementation file:

   ...

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

   ...

Which is it? From the signature I would strongly suspect it is supposed to be an instance member function of the IntegerSet class, and you have to provide the definition as a class member function (look at the form of those around your definition).

If so:

step 1/ fix the definition of emptySet to make it a member of IntegerSet.

Now what is an empty set and how would this be represented by your IntegerSet class?

An empty set is a set that has no members.

In the IntegerSet class an integer not in the [0..100] set is represented by a 0 set element for that integer. If the set is empty then no integers are in the set which would imply that all values' set elements will be 0.

You know (or have examples of) how to iterate over an array of values - e.g. in the

   IntegerSet::IntegerSet( int intArray[], int size)

constructor definition and elsewhere. So:

Step 2/ iterate over the set array member (called unsurprisingly set, or this->set if you want to be explicit) setting each element to zero.

Then remember to go back to the class definition and fix the default constructor definition:

Step 3/ add the call to the emptySet member function to the default constructor.

Now on to deleteElement.

I do not understand why the signature you have provided for the deleteElement member function passes a reference to another IntegerSet (in fact it could possibly be a reference to this set) and returns another IntegerSet object (as it is returned by value).

Was your thinking that it is supposed to delete each element in this set that is a member in the passed set? In which case would it not be more like a delete some elements operation? And what is the effect on this set and the returned set? Or were you just not thinking <grin/>!

If what your question states it should do is correct then maybe deleteElement should take an integer in the range [0..100] and not a reference to another IntegerSet and return nothing but modify this IntegerSet, that is it is similar in form to the insertElement operation.

Step 4/ Change the declaration and definition of deleteElement to match the form of the insertElement member function.

Note: you might also like to look at the implementation of the insertElement definition as the form of deleteElement is pretty much the same except that it deletes an element by setting its entry to 0 rather than inserts it by setting its entry to 1.

So what should you take away from this?

Primarily that even if you do not know or remember exactly the way to express things in the code that in this sort of assignment (an in fact in many real life development cases) there is already a lot of code to use as similar examples.

The second thing is to remember that there will be differences between your case and the example cases you refer to - so using you brain is important - think!

Oh and of course (in large friendly letters): Don't Panic!

There are quite a few other things I could say about the style of the presented code - such as the repeated use of the magic number 101 rather than the use of a named constant and a preference for post increment when pre increment would do as well)  but one thing I really think should be mentioned (which if you did not write all presented code yourself you might like to mention to the person who provided it):

   Whilst it is a good idea to use explicit using declarations rather than blanket
   using directives they should be placed _after_ _all_ #includes for the same
   reason they should not appear in header files. For the reasoning for this see:

       http://www.gotw.ca/gotw/053.htm

   Starting from "Characteristics of a Good Long-Term Solution", especially from
   "2. Namespace using declarations should never appear in header files." and the
   related item in Herb Sutter's excellent book "More Exceptional C++"
   "Item 40: Namespaces, Part 2: Migrating to Namespaces".

Hope this points you in the right direction and moves you forward with your assignment.

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Ralph McArdell

Expertise

I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.

Experience

My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at http://www.open-std.org/jtc1/sc22/wg21/.

Education/Credentials

©2016 About.com. All rights reserved.