Project 30
Home ] Up ]

 

//Project30.cpp
//Date 11/14/2001
//Author: Us

////////////////////////////////////////////////////
// Other changes made on   11/14/2001 //////////////
// count replaced with  m_count
// items replaced with  m_items 
// member replaced with this->member 
////////////////////////////////////////////////////


////////////////////////////////////////////////////
//includes
////////////////////////////////////////////////////
#include <iostream.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>


////////////////////////////////////////////////////
// constants
////////////////////////////////////////////////////
const int MAX_LEN = 20;

const int UNDEFINED = -99;

const char *testNames[] = 
  {
  "Chair", "Table", "Spoon", "Knife",
  "Phone", "Couch", "Drive", "Mouse", 
  "Clock", "Cable", "Plier", "Paper",
  "Stand", "Stool"
  };

const int testWeights[] =
  {
  11, 22, 33, 44, 55, 66, 
  77, 88, 99, 12, 13, 14, 
  15, 16
  };

const int MAX_NAMES = sizeof(testNames)/sizeof(testNames[0]);

const int MAX_ITEMS = 30;


////////////////////////////////////////////////////
// test functions
////////////////////////////////////////////////////
void testInput(void);
void testSetName(void);
void testSetWeight(void);
void testConstructor(void);
void testConstructorCh(void);
void testConstructorCopy(void);
void testSet(void);
void testOperatorEqual(void);
void testGetName(void);
void testGetWeight(void);
void testOperatorLessThan(void);
void testOperatorAssign(void);
void testOperatorInsertion(void);
void testOperatorExtraction(void);
void testConstructorCInventory(void);
void testConstructor2CInventory(void);
void testConstructor3CInventory(void);
void testSortBubbleCInventory(void);
void testIsSortedCInventory(void);
void testShuffleCInventory(void);
void testOperatorAssignCInventory(void);
void testSortSelectionCInventory(void);
void testSortInsertionCInventory(void);
void testSortByCountingCInventory(void);
void testDisplayDistinctCInventory(void);
void testInsertCInventory(void);
void testRemoveCInventory(void);
void testRemoveDupesCInventory(void);
void testCopyConstructorCInventory(void);     //  11/09/2001
void testOperatorEqualCInventory(void);       //  11/09/2001
void testOperatorLessThanOrEqual(void);       //  11/09/2001
void testOperatorGreaterThan(void);           //  11/09/2001
void testOperatorGreaterThanOrEqual(void);    //  11/09/2001
void testDisplaySummaryCountsCInventory(void);//  11/12/2001


////////////////////////////////////////////////////
// CItem class
////////////////////////////////////////////////////
class CItem
  {
  private:
    char m_name[MAX_LEN+1];
    int  m_weight;
  public:
    CItem(void); 
    CItem(char name[], int weight); 
    CItem(char ch); 
    CItem(const CItem &item); 
    void input(void);
    void display(void) const;
    void set(char name[], int weight);
    void setName(char name[]);
    void setWeight(int weight);
    char * getName(void);
    int getWeight(void);

    bool operator < (const CItem &i2);
    bool operator <= (const CItem &i2);               // 11/09/2001
    bool operator > (const CItem &i2);                // 11/09/2001
    bool operator >= (const CItem &i2);               // 11/09/2001

    CItem & operator = (const CItem &i2);

    friend bool operator ==(const CItem &i1, const CItem &i2);
    friend ostream & operator << (ostream &bob, const CItem &item);
    friend istream & operator >> (istream &joe, CItem &item);
  };


////////////////////////////////////////////////////
// CInventory class
////////////////////////////////////////////////////
class CInventory
  {
  private:
    int m_count;
    CItem m_items[MAX_ITEMS];
    void swap(CItem &i1, CItem &i2)
      {
      CItem tempItem;
      tempItem = i1;
      i1 = i2;
      i2 = tempItem;
      };
    
  public:
    CInventory(void);
    CInventory(int n);
    CInventory(char ch);
    CInventory(const CInventory &inv);                // 11/09/2001
    ~CInventory(void){}
    void sortBubble(void);
    bool isSorted(void);
    void shuffle(void);
    void sortSelection(void);                         // 11/09/2001
    void sortInsertion(void);
    void sortByCounting(void);
    void displayDistinct(void);
    bool insert(const CItem &item);                   // 11/02/2001
    bool remove(int index);                           // 11/05/2001
    int removeDupes(void);                            // 11/07/2001

    void displaySummaryCounts(void);                  // 11/12/2001

    int mergePurge(const CInventory &inv2);
    // myList.mergePurge(yourList);
    CInventory & mergePurge(const CInventory &inv2) const;
    // hisList = myList.mergePurge(yourList);
    friend CInventory & mergePurge(const CInventory &inv1, const CInventory &inv2);
    // hisList = mergePurge(myList, yourList);

    CInventory & operator = (const CInventory &inv2);
    bool operator == (const CInventory &inv2);        // 11/09/2001
    bool operator != (const CInventory &inv2);
    friend ostream & operator << (ostream &bob, const CInventory &inv);
    friend istream & operator >> (istream &joe, CInventory &inv);
  };

    
////////////////////////////////////////////////////
// main function
////////////////////////////////////////////////////
void main(void)
  {
  srand( (unsigned)time( NULL ) );

  //testInput();
  //testConstructor();
  //testConstructorCh();
  //testConstructorCopy();
  //testSetName();
  //testSetWeight();
  //testSet();
  //testOperatorEqual();
  //testGetName();
  //testGetWeight();
  //testOperatorLessThan();
  //testOperatorAssign();
  //testOperatorInsertion();
  //testOperatorExtraction();
  //mainProject03();
  //testConstructorCInventory();
  //testConstructor2CInventory();
  //testConstructor3CInventory();
  //testSortBubbleCInventory();
  //testIsSortedCInventory();
  //testShuffleCInventory();
  //testSortSelectionCInventory();
  //testSortInsertionCInventory();
  //testSortByCountingCInventory();
  //testOperatorAssignCInventory();
  //testDisplayDistinctCInventory();
  //testInsertCInventory();
  //testRemoveCInventory();
  //testRemoveDupesCInventory();
  //testCopyConstructorCInventory();
  //testOperatorEqualCInventory();
  //testOperatorLessThanOrEqual();
  //testOperatorGreaterThan();
  //testOperatorGreaterThanOrEqual();
  testDisplaySummaryCountsCInventory();

  }


////////////////////////////////////////////////////
//void CInventory::displaySummaryCounts(void);  
////////////////////////////////////////////////////
/*
displays the count and name of each item from the list
Input:  [72, 34, 72, 45, 72, 34]
          1   0   1   0   1   0
Output: 3 [72]
        2 [34]
        1 [45]

Algorithm 0:
Initialze the counts[] = 1
Initialze the visited[] = false
do the following for i=0 to count-1
  //find the first value not yet visited
  if visited[i] = false then
    visited[i] = 1;
    //find the duplicates on right of it
    for j=i+1 to count-1 do
      if items[i] == items[j] then
        counts[i]++
        visited[j] = true;
        end if
      end for j
    Display counts[i] and items[i]
    end if
  end for


Algorithm 1:
Initialze the visited[] = false
do the following for i=0 to count-1
  //find the first value not yet visited
  if visited[i] = false then
    visited[i] = true;
    dupes = 1
    //find the duplicates on right of it
    for j=i+1 to count-1 do
      if items[i] == items[j] then
        dupes++
        visited[j] = true;
        end if
      end for j
    Display dupes and items[i]
    end if
  end for
*/
////////////////////////////////////////////////////
//void CInventory::displaySummaryCounts(void)
////////////////////////////////////////////////////
void CInventory::displaySummaryCounts(void)
  {
  int i, j;

  //Initialze the visited[] = false
  bool visited[MAX_ITEMS];
  for (i=0; i<this->m_count; i++)
    visited[i] = false;

  int copies;
  int grandCount=0;

  for (i=0; i<this->m_count; i++)
    //find the first value not yet visited
    if (!visited[i])
      {
      visited[i] = true;
      copies = 1;
      //find the duplicates on right of it
      for (j=i+1; j<=this->m_count-1; j++)
        if (this->m_items[i] == this->m_items[j])
          {
          copies++;
          visited[j] = true;
          }
      cout << copies << ' ' << this->m_items[i];
      grandCount = grandCount + copies;
      }
  cout << "grandCount=" << grandCount << endl;
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testDisplaySummaryCountsCInventory
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testDisplaySummaryCountsCInventory(void)
  {
  cout << "testDisplaySummaryCountsCInventory\n";
  cout << "----------------------------------\n";
  for (int i=1; i<=5; i++)
    {
    cout << "Case #" << i << endl;
    CInventory myInv('r');

    cout << myInv;
    cout << "Summary counts\n";
    myInv.displaySummaryCounts();
    }
  }


////////////////////////////////////////////////////
// bool CInventory::operator == (const CInventory &inv2)
////////////////////////////////////////////////////
bool CInventory::operator == (const CInventory &inv2)
  {
  if (this->m_count != inv2.m_count) return false;

  for (int i=0; i<inv2.m_count; i++)
    if (!(this->m_items[i] == inv2.m_items[i])) 
      return false;

  return true;
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testOperatorEqualCInventory
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testOperatorEqualCInventory(void)
  {
  cout << "testOperatorEqualCInventory\n";
  cout << "---------------------------\n";
  for (int i=1; i<=5; i++)
    {
    CInventory myInv('r');
    CInventory yourInv(myInv);
    cout << myInv << endl;
    cout << yourInv << endl;

    if (myInv == yourInv) 
        cout << "Are equal\n";
      else
        cout << "Are NOT equal\n";
    }
  }


////////////////////////////////////////////////////
// CInventory::CInventory(const CInventory &inv)
////////////////////////////////////////////////////
CInventory::CInventory(const CInventory &inv)
  {
  this->m_count = inv.m_count;
  for (int i=0; i<inv.m_count; i++)
    this->m_items[i] = inv.m_items[i];
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testCopyConstructorCInventory
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testCopyConstructorCInventory(void)
  {
  cout << "testCopyConstructorCInventory\n";
  cout << "-----------------------------\n";
  for (int i=1; i<=5; i++)
    {
    CInventory myInv('r');
    CInventory yourInv(myInv);
    cout << myInv << endl;
    cout << yourInv << endl;

    if (myInv == yourInv) 
        cout << "Worked\n";
      else
        cout << "DID NOT WORK\n";
    }
  }


////////////////////////////////////////////////////
//int CInventory::removeDupes(void)
////////////////////////////////////////////////////
/*
  Removes duplicate records from the object
  returns the number of records removed

  [12, 22, 19, 19, 22, 12]
  [12, 22, 19, 22, 12]
  [12, 22, 19]

  Algorithm0:
  Go from left to right deleting duplicates

  Algorithm1:
  i=0
  Shoot dupes from j=i+1 to count-1
  i=i+1
  goto Shoot statement if i<count-1

  Algorithm2:
  i=0
  while i < count-1
    Shoot dupes from j=i+1 to count-1
    i=i+1
    end while

  [66 25 19]
    0  1  2
    count=3
  i  j  
  0  1..2
  1  2..2
  2 

  Algorithm3:
  i=0
  countRemoved=0
  while i < count-1
    //Shoot dupes from j=i+1 to count-1
    for j=i+1 to count-1
      if items[i] = items[j] then
        remove(j)
        increase countRemoved by 1
        end if

    i=i+1
    end while

*/
////////////////////////////////////////////////////
int CInventory::removeDupes(void)
  {
  int i=0, j;
  int countRemoved = 0;

  while (i < this->m_count-1)
    {
    //Shoot dupes from j=i+1 to count-1
    j=i+1; 
    while (j<=this->m_count-1)
      {
      if (this->m_items[i] == this->m_items[j])
          {
          this->remove(j);
          countRemoved++;
          }
        else
          j++;
      }

    i++;
    }

  return countRemoved;
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testRemoveCInventory
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testRemoveDupesCInventory(void)
  {
  cout << "testRemoveDupesCInventory\n";
  cout << "=========================\n";
  for (int i=0; i<=5; i++)
    {
    CInventory yourInv('r');

    cout << "Original\n";
    cout << yourInv;


    cout << "Removed " << yourInv.removeDupes() << endl;

    cout << yourInv;

    cout << "-------------------\n";
    }

  }


////////////////////////////////////////////////////
// CInventory::remove(int index)
////////////////////////////////////////////////////
/* 
  delete the item at index in range (0..count-1)
  Possibilities:
    index > count-1
    index < 0
    index >= 0 and <=count-1

Version 0:

  if index is out of range then 
    return false
  else
    delete item at index position
    return true
  end if


Version 1:

  if index <0 or index > count-1
    return false
  else
    //delete item at index position
    for i=index to count-2
      items[i] = items[i+1]
      end for

    items[count-1] = nothing
    count--
    return true
  end if

*/
////////////////////////////////////////////////////
bool CInventory::remove(int index)
  {
  if ((index <0) || (index > this->m_count-1))
    return false;
  else
    //delete item at index position
    {
    for (int i=index; i<=this->m_count-2; i++)
      this->m_items[i] = this->m_items[i+1];

    CItem nullItem;
    this->m_items[m_count-1] = nullItem;
    this->m_count--;
    return true;
    }

  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testRemoveCInventory
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testRemoveCInventory(void)
  {
  cout << "testRemoveCInventory\n";
  cout << "====================\n";
  for (int i=0; i<=5; i++)
    {
    CInventory yourInv('r');

    cout << "Original\n";
    cout << yourInv;

    int index = rand()%10;
    cout << "Attempting to remove item at "<< index << endl;

    if(yourInv.remove(index))
        cout << "Removed\n";
      else
        cout << "Not removed\n";

    cout << yourInv;

    cout << "-------------------\n";
    }

  }


////////////////////////////////////////////////////
// bool CInventory::insert(const CItem &item)
////////////////////////////////////////////////////
  /*insert item to inventory

  if count = MAX_ITEMS then return false
  items[count] = item
  count++
  return true
  */
////////////////////////////////////////////////////
bool CInventory::insert(const CItem &item) //11/02/2001
  {
  if (MAX_ITEMS == this->m_count)
       return false;
    else
      {
      this->m_items[m_count] = item;
      this->m_count++;
      return true;
      }
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testInsertCInventory
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testInsertCInventory(void)
  {
  cout << "testInsertCInventory\n";
  cout << "====================\n";
  for (int i=0; i<=5; i++)
    {
    CInventory *invPtr;

    if (rand()%2)
        invPtr = new CInventory('r');
      else
        invPtr = new CInventory(MAX_ITEMS);

    cout << "Original\n";
    cout << *invPtr;
    
    CItem item('r');

    if(invPtr->insert(item))
        cout << "success\n";
      else
        cout << "OVERFLOW\n";

    cout << "After inserting " << item;
    cout << *invPtr;

    cout << "-------------------\n";
    }
  }


////////////////////////////////////////////////////
//  void displayDistinct(void);
////////////////////////////////////////////////////
/*
input: [23, 21, 23, 13, 21, 21, 16, 13]
output:[23, 21, 13, 16]

Algorithm0:
display the first value
From 2nd to last display if not displayed

Algorithm1:
display items[0]
for i=1 to count-1 do the following
  display items[i] if not displayed

Algorithm2:
display items[0]
for i=1 to count-1 do the following
  display items[i] if it does not match with any previous value

Algorithm3:
display items[0]
for i=1 to count-1 do the following
  if items[i] <> items[0..i-1] then display it


Algorithm4:
display items[0]
for i=1 to count-1 do the following
  visited = false
  for j=0 to i-1 do the following
    if items[i] = items[j] then visited = true
    end for
  if not visited then display items[i]
  end for

Algorithm5:
display items[0]
for i=1 to count-1 do the following
  visited = false
  for j=0 to i-1 do the following
    if items[i] = items[j] then 
      visited = true
      get out of this for loop
      end if
    end for
  if not visited then display items[i]
  end for

Algorithm6:
if count <= 0 exit function
display items[0]
for i=1 to count-1 do the following
  visited = false
  for j=0 to i-1 do the following
    if items[i] = items[j] then 
      visited = true
      get out of this for loop
      end if
    end for
  if not visited then display items[i]
  end for

Algorithm7:
for i=0 to count-1 do the following
  visited = false
  for j=0 to i-1 do the following
    if items[i] = items[j] then 
      visited = true
      get out of this for loop
      end if
    end for
  if not visited then display items[i]
  end for

*/
////////////////////////////////////////////////////
void CInventory::displayDistinct(void)
  {
  for (int i=0; i<=this->m_count-1; i++)
    {
    bool visited = false;
    for(int j=0; j<=i-1; j++)
      if (this->m_items[i] == this->m_items[j]) 
        {
        visited = true;
        break;
        }

    if (!visited) cout << this->m_items[i];
    }
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testDisplayDistinctCInventory
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testDisplayDistinctCInventory(void)
  {
  cout << "testDisplayDistinctCInventory\n";
  cout << "=============================\n";
  for (int i=0; i<=5; i++)
    {
    CInventory yourInv('r');

    cout << "Original\n";
    cout << yourInv;
    
    cout << "DIstinct\n";
    yourInv.displayDistinct();

    cout << "-------------------\n";
    }

  for (i=0; i<=5; i++)
    {
    CInventory *invPtr;

    invPtr = new CInventory('r');

    cout << "Original\n";
    cout << invPtr << endl;
    cout << *invPtr;

    cout << "-------------------\n";
    }
  }


////////////////////////////////////////////////////
//void sortByCounting(void);
////////////////////////////////////////////////////
//Sorting by counting
/*
items[] = [66, 37, 29, 28, 61, 98]
counts[]= { 0,  0,  0,  0,  0,  0}

[66, 37, 29, 28, 61, 98]
{ 0,  0,  0,  0,  0,  0}

[66, 37, 29, 28, 61, 98]
{ 4,  0,  0,  0,  0,  1}

[66, [37, 29, 28, 61, 98]
{ 4, [2,  0,  0,  1,  2}

[66, 37, [29, 28, 61, 98]
{ 4, 2,  [1,  0,  2,  3}

[66, 37, 29, [28, 61, 98]
{ 4, 2,  1,  [0,  3,  4}

[66, 37, 29, 28, [61, 98]
{ 4, 2,  1,  0,  [3,  5}

[66, 37, 29, 28, 61, 98] is items[]
{ 4, 2,  1,  0,  3,  5}  is counts[]


place values based on counts
[28, 29, 37, 61, 66, 98] is tItems[]
  0   1   2   3   4   5 

Version 0:
Initialize the counts[]
Update the counts[] by incrementing
Place values in a new list based on counts[]
Copy new list to old list

Version 1:
//Initialize the counts[]
  for i=0 to count-1
    counts[i] = 0

//Update the counts[] by incrementing
  for i=0 to count-2
    for j=i+1 to count-1
      if items[i] > items[j] then
          counts[i]++
        else
          counts[j]++
        end if
      end for
    end for

//Place values in a tItems[] based on counts[]
  for i=0 to count-1
    tItems[counts[i]] = items[i]
    end for
  
//Copy new list to old list
  for i=0 to count-1
    items[i] = tItems[i]
    end for

*/
////////////////////////////////////////////////////
void CInventory::sortByCounting(void)
  {
//Initialize the counts[]
  int counts[MAX_ITEMS];

  for (int i=0; i<=this->m_count-1; i++)
    counts[i] = 0;

  int k;
  cout << "counts[]: ";
  for (k=0; k<=this->m_count-1; k++)
    cout << counts[k] << ' ';
  cout << endl;

//Update the counts[] by incrementing
  int j;

  for (i=0; i<=this->m_count-2; i++) //because last value is lonely
    for (j=i+1; j<=this->m_count-1; j++)
      {
      if (this->m_items[j] < this->m_items[i])
          counts[i]++;
        else
          counts[j]++;

      cout << "counts[]: ";
      for (k=0; k<=this->m_count-1; k++)
        cout << counts[k] << ' ';
      cout << endl;
      }

//Place values in a tItems[] based on counts[]
  CItem tItems[MAX_ITEMS];

  for (i=0; i<=this->m_count-1; i++)
    tItems[counts[i]] = this->m_items[i];
  
//Copy new list to old list
  for (i=0; i<=this->m_count-1; i++)
    this->m_items[i] = tItems[i];

  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testSortByCountingCInventory
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testSortByCountingCInventory(void)
  {
  cout << "testSortByCountingCInventory\n";
  cout << "============================\n";
  for (int i=0; i<=5; i++)
    {
    CInventory yourInv('r');

    cout << yourInv;

    cout << "After sortByCounting\n";
  
    yourInv.sortByCounting();
    cout << yourInv;

    if (yourInv.isSorted())
        cout << "SORTED\n";
      else
        cout << "NOT SORTED NOT SORTED\n";

    cout << "-------------------\n";
    }
  }


////////////////////////////////////////////////////
//void CInventory::sortInsertion(void)
////////////////////////////////////////////////////
/*
/* Algorithm:
[66], 37, 29, 28, 61, 98
[37, 66], 29, 28, 61, 98
[29, 37, 66], 28, 61, 98
[28, 29, 37, 66], 61, 98
[28, 29, 37, 61, 66], 98
[28, 29, 37, 61, 66, 98]

Version 0:
---------
if count <= 1 then exit function
do the following count-1 times using i=1 to count-1
  insert the ith value s.t. items[0..i] are sorted

Version 1:
---------
if count <= 1 then exit function
do the following count-1 times using i=1 to count-1
  //insert the ith value s.t. items[0..i] are sorted
  k = i
  step1:
  if item[k] >= items[k-1] then exit for
    else
     swap items[k], items[k-1]
     k = k-1
     if k > 0 then goto step1:

Version 2:
---------
if count <= 1 then exit function
do the following count-1 times using i=1 to count-1
  //insert the ith value s.t. items[0..i] are sorted
  k = i
  do
    {
    if item[k] >= items[k-1] then 
        exit do (inner)
      else
        swap items[k], items[k-1]
        k = k-1
      end if
    }
    while (k>0)
  end do (outer)


Version 3:
---------
if count <= 1 then exit function
do the following count-1 times using i=1 to count-1
  //insert the ith value s.t. items[0..i] are sorted
  k = i
  while k > 0
    if item[k] >= items[k-1] then 
        exit do (inner)
      else
        swap items[k], items[k-1]
        k = k-1
      end if
    end while
  end do (outer)


Version 4:
---------
do the following count-1 times using i=1 to count-1
  //insert the ith value s.t. items[0..i] are sorted
  k = i
  while k > 0
    if item[k] >= items[k-1] then 
        exit do (inner)
      else
        swap items[k], items[k-1]
        k = k-1
      end if
    end while
  end do (outer)

*/
////////////////////////////////////////////////////
void CInventory::sortInsertion(void)
  {
  int k;

  for (int i=1; i<= this->m_count-1; i++)
    {
    k = i;
    while (k > 0)
      {
      if (!(this->m_items[k] < this->m_items[k-1]))  
          break;
        else
          {
          swap(this->m_items[k], this->m_items[k-1]);
          k = k-1;
          }
      }
    }
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testSortInsertionCInventory
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testSortInsertionCInventory(void)
  {
  cout << "testSortInsertionCInventory\n";
  cout << "===========================\n";
  for (int i=0; i<=5; i++)
    {
    CInventory yourInv('r');

    cout << yourInv;

    cout << "After sortInsertion\n";

    yourInv.sortInsertion();
    cout << yourInv;

    if (yourInv.isSorted())
        cout << "SORTED\n";
      else
        cout << "NOT SORTED NOT SORTED\n";

    cout << "-------------------\n";
    }
  }


////////////////////////////////////////////////////
//void CInventory::sortSelection(void)
/* Algorithm:
[66, 37, 29, 28, 61]
[61, 37, 29, 28] 66
[28, 37, 29,] 61 66
[28, 29,] 37, 61 66
[28,]29,  37, 61 66

Version #0
Given: items[0..count-1]
n = count
do the following count-1 times
  put the index of the max value in iMax
  swap items[iMax], items[n-1]
  n = n-1
  end do

Version #1
Given: items[0..count-1]
n = count
do the following count-1 times
  //put the index of the max value in iMax
  iMax = 0
  do the following n-1 times using k=1 to n-1
    if items[k] > items[iMax] then
      iMax = k
      end if
    end do
  swap items[iMax], items[n-1]
  cout << *this
  n = n-1
  end do
  
testSortSelection
do the following 5 times
  CInventory testInv('r')
  display "Original inv"
  display testInv
  tetInv.sortSelection()
  display "Sorted inv"
  end do

*/
////////////////////////////////////////////////////
// sortSelection(void)
////////////////////////////////////////////////////
void CInventory::sortSelection(void)
  {
  int n = this->m_count; 
  int k;
  for (int i=1; i<=this->m_count-1; i++)
    {
    //put the index of the max value in iMax
    int iMax = 0;
    for (k=1; k<=n-1; k++)
      if (this->m_items[iMax] < this->m_items[k])
        iMax = k;
    swap(this->m_items[iMax], this->m_items[n-1]);
    n = n-1;
    }
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testSortSelectionCInventory
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testSortSelectionCInventory(void)
  {
  cout << "testSortSelectionCInventory\n";
  cout << "===========================\n";
  for (int i=0; i<=5; i++)
    {
    CInventory yourInv('r');

    cout << yourInv;

    cout << "After sortSelection\n";

    yourInv.sortSelection();
    cout << yourInv;

    if (yourInv.isSorted())
        cout << "SORTED\n";
      else
        cout << "NOT SORTED NOT SORTED\n";

    cout << "-------------------\n";
    }
  }


////////////////////////////////////////////////////
// operator =
////////////////////////////////////////////////////
CInventory & CInventory::operator = (const CInventory &inv2)
  {
  this->m_count = inv2.m_count;
  for (int i=0; i<this->m_count; i++)
    this->m_items[i] = inv2.m_items[i];

  return *this;
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testOperatorAssignCInventory
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testOperatorAssignCInventory(void)
  {
  cout << "testOperatorAssignCInventory\n";
  cout << "============================\n";
  for (int i=1; i<=5; i++)
    {
    CInventory yourInv('r');
    CInventory myInv('R');
    CInventory hisInv('r');

    cout << "yourInv = " << yourInv << endl;
    cout << "myInv   = " << myInv << endl;
    cout << "hisInv  = " << hisInv << endl;

    yourInv = myInv = hisInv;

    cout << "After yourInv = myInv = hisInv;\n";

    cout << "yourInv = " << yourInv << endl;
    cout << "myInv   = " << myInv << endl;
    cout << "hisInv  = " << hisInv << endl;
    cout << "----------------------\n";
    }
  }


////////////////////////////////////////////////////
// shuffle function
////////////////////////////////////////////////////
void CInventory::shuffle(void)
  {
  if (this->m_count <= 1)
    return;

  CItem tempItem;
  int pick1, pick2;

  for (int i=1; i<=2*this->m_count; i++)
    {
    pick1 = rand()%this->m_count;
    pick2 = rand()%this->m_count;

    swap(this->m_items[pick1], this->m_items[pick2]);
    /*
    tempItem = this->m_items[pick1];
    this->m_items[pick1] = this->m_items[pick2];
    this->m_items[pick2] = tempItem;
    */
    }
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testShuffleCInventory
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testShuffleCInventory(void)
  {
  cout << "testShuffleCInventory\n";
  cout << "=====================\n";
  for (int i=0; i<=5; i++)
    {
    CInventory yourInv('r');

    cout << yourInv;
    if (yourInv.isSorted())
        cout << "SORTED\n";
      else
        cout << "NOT SORTED NOT SORTED\n";

    cout << "After sortBubble\n";

    yourInv.sortBubble();
    cout << yourInv;
    if (yourInv.isSorted())
        cout << "SORTED\n";
      else
        cout << "NOT SORTED NOT SORTED\n";

    cout << "After shuffle\n";

    yourInv.shuffle();
    cout << yourInv;
    if (yourInv.isSorted())
        cout << "SORTED\n";
      else
        cout << "NOT SORTED NOT SORTED\n";

    cout << "-------------------\n";
    }
  }


////////////////////////////////////////////////////
// isSorted function
////////////////////////////////////////////////////
bool CInventory::isSorted(void)
  {
  for (int i=0; i<=this->m_count-2; i++)
    if (this->m_items[i+1] < this->m_items[i]) 
      return false;

  return true;
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testIsSortedCInventory
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testIsSortedCInventory(void)
  {
  cout << "testIsSortedCInventory\n";
  cout << "======================\n";
  for (int i=0; i<=5; i++)
    {
    CInventory yourInv('r');

    cout << yourInv;
    if (yourInv.isSorted())
        cout << "SORTED\n";
      else
        cout << "NOT SORTED NOT SORTED\n";

    cout << "After sortBubble\n";

    yourInv.sortBubble();
    cout << yourInv;
    if (yourInv.isSorted())
        cout << "SORTED\n";
      else
        cout << "NOT SORTED NOT SORTED\n";

    cout << "-------------------\n";
    }
  }


////////////////////////////////////////////////////
// sortBubble function
////////////////////////////////////////////////////
void CInventory::sortBubble(void)
  {
  bool sorted;
  int i;
  CItem tempItem;

  do 
    {
    sorted = true;
    for (i=0; i<=this->m_count-2; i++)
      {
      if (this->m_items[i+1] < this->m_items[i])
          {
          //use swap
          tempItem = this->m_items[i];
          this->m_items[i] = this->m_items[i+1];
          this->m_items[i+1] = tempItem;
          sorted = false;
          }
      }
    }
    while (!sorted);

  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testSortBubbleCInventory
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testSortBubbleCInventory(void)
  {
  cout << "testSortBubbleCInventory\n";
  cout << "========================\n";
  for (int i=0; i<=5; i++)
    {
    CInventory yourInv('r');

    cout << yourInv;

    cout << "After sortBubble\n";

    yourInv.sortBubble();
    cout << yourInv;
    cout << "-------------------\n";
    }
  }


////////////////////////////////////////////////////
// construct inventory of random random items
////////////////////////////////////////////////////
CInventory::CInventory(char ch)
  {
  if (('r' == ch) || ('R' == ch))
    {
    this->m_count = rand()%MAX_ITEMS;

    for (int i=0; i<=this->m_count-1; i++)
      {
      CItem item('r');
      this->m_items[i] = item;
      }
    }
  else
    this->m_count =0;

  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testConstructor3CInventory
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testConstructor3CInventory(void)
  {
  cout << "testConstructor3CInventory\n";
  cout << "=========================\n";
  for (int i=1; i<=5; i++)
    {
    CInventory yourInv('r');
    CInventory myInv('R');
    CInventory hisInv('s');

    cout << yourInv;
    cout << endl;
    cout << myInv;
    cout << endl;
    cout << hisInv;
    cout << "-------------------\n";
    }
  }


////////////////////////////////////////////////////
// construct inventory of n random items
////////////////////////////////////////////////////
CInventory::CInventory(int n)
  {
  if (n < 0) 
    n = -n;

  this->m_count = n;

  for (int i=0; i<=n-1; i++)
    {
    CItem item('r');
    this->m_items[i] = item;
    }

  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testConstructor2CInventory
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testConstructor2CInventory(void)
  {
  cout << "testConstructor2CInventory\n";
  cout << "=========================\n";
  for (int i=-1; i<=5; i++)
    {
    CInventory yourInv(i);
    cout << yourInv;
    cout << "-------------------\n";
    }
  }


////////////////////////////////////////////////////
// operator << overloaded for CInventory
////////////////////////////////////////////////////
ostream & operator << (ostream &bob, const CInventory &inv)
  {
  bob << "inventory(" << inv.m_count << ")=\n";

  for (int i=0; i<=inv.m_count-1; i++)
    bob << inv.m_items[i];

  return bob;
  }


////////////////////////////////////////////////////
// default constructor for CInventory
////////////////////////////////////////////////////
CInventory::CInventory(void)
  {
  m_count = 0;
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testConstructorCInventory
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testConstructorCInventory(void)
  {
  cout << "testConstructorCInventory\n";
  cout << "=========================\n";
  for (int i=1; i<=5; i++)
    {
    CInventory yourInv;
    cout << yourInv;
    cout << "-------------------\n";
    }
  }


////////////////////////////////////////////////////
//overload >> for CItem
////////////////////////////////////////////////////
istream & operator >> (istream &joe, CItem &item)
  {
  cout << "item m_name:   ";
  joe >> item.m_name;
  cout << "item m_weight: ";
  joe >> item.m_weight;
  return joe;
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// test operator >>
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testOperatorExtraction(void)
  {
  cout << "Test operator >>\n";
  cout << "=================\n";
  for (int i=1; i<=5; i++)
    {
    CItem item1;

    cin >> item1;
    cout << item1;

    cout << "---------------------------\n";
    }
  }


////////////////////////////////////////////////////
//overload << for CItem
////////////////////////////////////////////////////
ostream & operator << (ostream &bob, const CItem &item)
  {
  bob << '[' << item.m_name << ", ";
  bob << item.m_weight << ']' << endl;
  return bob;
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// test operator <<
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testOperatorInsertion(void)
  {
  cout << "Test operator <<\n";
  cout << "=================\n";
  for (int i=1; i<=5; i++)
    {
    CItem item1('r');

    cout << "item1 = "; item1.display();
    cout << "item1 = " << item1 << endl;

    cout << item1 << item1;

    cout << "---------------------------\n";
    }
  }


////////////////////////////////////////////////////
// operator = overloaded
////////////////////////////////////////////////////
CItem & CItem::operator = (const CItem &i2)
  {
  strcpy(m_name, i2.m_name);
  this->m_weight = i2.m_weight;
  return *this;
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testOperatorAssign
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testOperatorAssign(void)
  {
  cout << "Test operator =\n";
  cout << "===============\n";
  for (int i=1; i<=5; i++)
    {
    CItem item1('r'), item2('r'), item3('r');

    cout << "item1 = "; item1.display();
    cout << "item2 = "; item2.display();
    cout << "item3 = "; item3.display();

    item1 = item2 = item3;
    //item1.operator= (item2.operator= item3);
    //item1.operator = (item2.operator = (item3));
    item2.operator = (item3);
    item1.operator = (item2);

    cout << "After item1 = item2 = item3;\n";
    cout << "item1 = "; item1.display();
    cout << "item2 = "; item2.display();
    cout << "item3 = "; item3.display();

    cout << "---------------------------\n";
    }
  }


////////////////////////////////////////////////////
// operator >= overloaded  for CItem class objects
// returns true if weight of i1 is >= that of i2
// else returns false
////////////////////////////////////////////////////
bool CItem::operator >= (const CItem &i2)
  {
  return !(*this < i2); 
  //return (this->m_weight >= i2.m_weight);
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testOperatorGreaterThanOrEqual
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testOperatorGreaterThanOrEqual(void)
  {
  cout << "Test operator >=\n";
  cout << "================\n";
  for (int i=1; i<=5; i++)
    {
    CItem item1('r'), item2('r'), item3('r');

    cout << "item1 = "; item1.display();
    cout << "item2 = "; item2.display();
    cout << "item3 = "; item3.display();

    if (item1 >= item2)
        cout << "item1 is >= item2\n";
      else
        cout << "item1 is not >= item2\n";

    if (item1 >= item3)
        cout << "item1 is >= item3\n";
      else
        cout << "item1 is not >= item3\n";

    cout << "---------------------------\n";
    }
  }


////////////////////////////////////////////////////
// operator > overloaded  for CItem class objects
// returns true if weight of i1 is > that of i2
// else returns false
////////////////////////////////////////////////////
bool CItem::operator > (const CItem &i2)
  {
  return (this->m_weight > i2.m_weight);
  // return !(*this <= i2); 
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testOperatorGreaterThan
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testOperatorGreaterThan(void)
  {
  cout << "Test operator >\n";
  cout << "===============\n";
  for (int i=1; i<=5; i++)
    {
    CItem item1('r'), item2('r'), item3('r');

    cout << "item1 = "; item1.display();
    cout << "item2 = "; item2.display();
    cout << "item3 = "; item3.display();

    if (item1 > item2)
        cout << "item1 is > item2\n";
      else
        cout << "item1 is not > item2\n";

    if (item1 > item3)
        cout << "item1 is > item3\n";
      else
        cout << "item1 is not > item3\n";

    cout << "---------------------------\n";
    }
  }


////////////////////////////////////////////////////
// operator <= overloaded  for CItem class objects
// returns true if weight of i1 is <= that of i2
// else returns false
////////////////////////////////////////////////////
bool CItem::operator <= (const CItem &i2)
  {
  return (this->m_weight <= i2.m_weight); 
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testOperatorLessThanOrEqual
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testOperatorLessThanOrEqual(void)
  {
  cout << "Test operator <=\n";
  cout << "================\n";
  for (int i=1; i<=5; i++)
    {
    CItem item1('r'), item2('r'), item3('r');

    cout << "item1 = "; item1.display();
    cout << "item2 = "; item2.display();
    cout << "item3 = "; item3.display();

    if (item1 <= item2)
        cout << "item1 is <= item2\n";
      else
        cout << "item1 is not <= item2\n";

    if (item1 <= item3)
        cout << "item1 is <= item3\n";
      else
        cout << "item1 is not <= item3\n";

    cout << "---------------------------\n";
    }
  }


////////////////////////////////////////////////////
// operator < overloaded  for CItem class objects
// returns true if weight of i1 is less than that of i2
// else returns false
////////////////////////////////////////////////////
bool CItem::operator < (const CItem &i2)
  {
  return (this->m_weight < i2.m_weight); 
  
  /*
  if (this->m_weight < i2.m_weight) 
      return true;
    else
      return false;
  */
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testOperatorLessThan
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testOperatorLessThan(void)
  {
  cout << "Test operator <\n";
  cout << "===============\n";
  for (int i=1; i<=5; i++)
    {
    CItem item1('r'), item2('r'), item3('r');

    cout << "item1 = "; item1.display();
    cout << "item2 = "; item2.display();
    cout << "item3 = "; item3.display();

    if (item1 < item2)
        cout << "item1 is lighter than item2\n";
      else
        cout << "item1 is not lighter than item2\n";

    if (item1 < item3)
        cout << "item1 is lighter than item3\n";
      else
        cout << "item1 is not lighter than item3\n";

    cout << "---------------------------\n";
    }
  }


////////////////////////////////////////////////////
// getWeight
// returns the weight
////////////////////////////////////////////////////
int CItem::getWeight(void)
  {
  return this->m_weight;
  };


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testGetWeight
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testGetWeight(void)
  {
  cout << "test getWeight\n";
  for (int i=1; i<=5; i++)
    {
    CItem i('r');

    cout << "item = "; i.display();

    cout << "weight = " << i.getWeight() << endl;
    cout << "-----------------------------\n";
    }
  }


////////////////////////////////////////////////////
// getName
// returns the name
////////////////////////////////////////////////////
char * CItem::getName(void)
  {
  return this->m_name;
  };


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testGetName
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testGetName(void)
  {
  cout << "test getName\n";
  for (int i=1; i<=5; i++)
    {
    CItem i('r');

    cout << "item = "; i.display();

    cout << "name = " << i.getName() << endl;
    cout << "-----------------------------\n";
    }
  }


////////////////////////////////////////////////////
// operator ==
// compares two items for equality
////////////////////////////////////////////////////
bool operator ==(const CItem &i1, const CItem &i2)
  {
  //return (c1&&c2);

  if (i1.m_weight != i2.m_weight) 
      return false;

  if (strcmp(i1.m_name, i2.m_name) != 0) 
      return false;

  return true;
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testOperatorEqual
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testOperatorEqual(void)
  {
  cout << "Test operator equal\n";
  cout << "===================\n";
  for (int i=1; i<=5; i++)
    {
    CItem item1('r'), item2('r'), item3(item1);

    cout << "item1 = "; item1.display();
    cout << "item2 = "; item2.display();
    cout << "item3 = "; item3.display();

    if (item1 == item2)
        cout << "item1 is equal to item2\n";
      else
        cout << "item1 is not equal to item2\n";

    if (item1 == item3)
        cout << "item1 is equal to item3\n";
      else
        cout << "item1 is not equal to item3\n";


    cout << "---------------------------\n";
    }
  }


////////////////////////////////////////////////////
// setWeight(int weight)
// sets the m_weight data member to weight
////////////////////////////////////////////////////
void CItem::setWeight(int weight)
  {
  this->m_weight = weight;
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testSetWeight
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testSetWeight(void)
  {
  cout << "Test setWeight(weight)\n";
  for (int i=1; i<=5; i++)
    {
    CItem item('r');
    item.display();

    int tWeight = rand()%100;

    cout << "tWeight = " << tWeight  << endl;

    item.setWeight(tWeight);

    cout << "After item1.setWeight(tWeight);\n";
    item.display();
    cout << "---------------------------\n";
    }
  }


////////////////////////////////////////////////////
// setName(char name)
// sets the m_name data member to name
////////////////////////////////////////////////////
void CItem::setName(char name[])
  {
  strcpy(this->m_name, name);
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testSetName
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testSetName(void)
  {
  cout << "Test setName(name)\n";
  for (int i=1; i<=5; i++)
    {
    CItem item('r');
    item.display();

    int i = rand()%MAX_NAMES;
    char tName[MAX_LEN+1];
    strcpy(tName, testNames[i]);

    cout << "tName = \"" << tName << "\"" << endl;

    item.setName(tName);

    cout << "After item1.setName(tName);\n";

    item.display();
    cout << "---------------------------\n";
    }
  }


////////////////////////////////////////////////////
//CItem (item) copy constructor
// constructs an object which is a copy given object
////////////////////////////////////////////////////
CItem::CItem(const CItem &item)
  {
  strcpy(this->m_name, item.m_name);
  this->m_weight = item.m_weight;
  //(*this).m_weight = item.m_weight;
  //cout << "copy constructor called\n";
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testConstructorCopy
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testConstructorCopy(void)
  {
  cout << "Test copy Constructor\n";
  for (int i=1; i<=5; i++)
    {
    CItem item1('r');
    CItem item2(item1);
    item1.display();
    item2.display();
    }
  }


////////////////////////////////////////////////////
//CItem (ch) constructor
// constructs an object with random name and weight
////////////////////////////////////////////////////
CItem::CItem(char ch)
  {
  if ('r' == ch )
      {
      int i = rand()%MAX_NAMES;
      strcpy(this->m_name, testNames[i]);
      this->m_weight = testWeights[i];
      }
    else
      {
      strcpy(this->m_name, "");
      this->m_weight = -99;
      }
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testConstructorCh
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testConstructorCh(void)
  {
  cout << "Test ConstructorCh\n";
  CItem item1('r');
  CItem item2('m');
  item1.display();
  item2.display();
  }

    
////////////////////////////////////////////////////
//CItem (name, weight) constructor
// constructs an object with given name and weight
////////////////////////////////////////////////////
CItem::CItem(char name[], int weight)
  {
  strcpy(this->m_name, name);
  this->m_weight = weight;
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testConstructor
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testConstructor(void)
  {
  cout << "Test Constructor(name, weight)\n";
  CItem item("Chair", 150);
  item.display();
  }


////////////////////////////////////////////////////
// display 
////////////////////////////////////////////////////
void CItem::display(void) const
  {
  cout << '[' << this->m_name << ", ";
  cout << this->m_weight << ']' << endl;
  }


////////////////////////////////////////////////////
//constructor default
////////////////////////////////////////////////////
CItem::CItem(void)
  {
  //cout << "Default Constructor called\n";
  strcpy(this->m_name, "");
  this->m_weight = -99;
  }


////////////////////////////////////////////////////
//input function
// This is a member function for CItem class
// it gets the name and weight from the keyboard
// and sets the values of name and weight data members
////////////////////////////////////////////////////
void CItem::input(void)
  {
  cout << "item m_name:   ";
  cin >> this->m_name;
  cout << "item m_weight: ";
  cin >> this->m_weight;
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testInput
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testInput(void)
  {
  cout << "test input function\n";
  CItem item1;
  item1.display();
  item1.input();
  item1.display();
  }


////////////////////////////////////////////////////
// set(name, weight)
////////////////////////////////////////////////////
void CItem::set(char name[], int weight)
  {
  strcpy(this->m_name, name);
  this->m_weight = weight;
  }


//++++++++++++++++++++++++++++++++++++++++++++++++++
// testSet
//++++++++++++++++++++++++++++++++++++++++++++++++++
void testSet(void)
  {
  cout << "Test set(name, weight)\n";
  for (int i=1; i<=5; i++)
    {
    CItem item('r');
    item.display();
    int i = rand()%MAX_NAMES;
    char tName[MAX_LEN+1];
    strcpy(tName, testNames[i]);
    cout << "tName = \"" << tName << "\"" << endl;

    int tWeight = rand()%100;
    cout << "tWeight = " << tWeight  << endl;

    item.set(tName, tWeight);
    cout << "After item.set(tName, tWeight);\n";
    item.display();
    cout << "------------------------------------\n";
    }
  }