p04Books03
Home ] Up ]

 

//p04books03
//author
//date 07/24/2001
/*
Project #6 sort by title
test function
*/


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


//////////////////////////////////////////////////////////////////////
//constants
//////////////////////////////////////////////////////////////////////
const int TITLE_LEN = 30;
const int AUTHOR_LEN = 30;
const int MAX_BOOKS = 15;


//////////////////////////////////////////////////////////////////////
//test values
//////////////////////////////////////////////////////////////////////
const char *testTitles[] = 
  {
  "C++ with Pizza Flavor", "Java Learn Now", "COBOL How To Forget",
  "FORTRAN 77", "DB2: An Introduction", "XML In 24 Hours",
  "UNIX"
  };

const int MAX_TITLES = sizeof(testTitles)/sizeof(testTitles[0]);

const char *testAuthors[] = 
  {
  "John", "Adam", "Sumeer", "Natalie", "David", "Rustin"
  };

const int MAX_AUTHORS = sizeof(testAuthors)/sizeof(testAuthors[0]);

const int testYears[] = {1977, 1988, 1989, 1991, 2000, 2001};

const int MAX_YEARS = sizeof(testYears)/sizeof(testYears[0]);


void testSortByYear(void);
void testAdd(void);


//////////////////////////////////////////////////////////////////////
//BookType class definition
//////////////////////////////////////////////////////////////////////
class CBook
  {
  private:
    char title[TITLE_LEN+1];
    char author[AUTHOR_LEN+1];
    int year;
    CBook *next;
  public:
    CBook(void);
    CBook(char t[], char a[], int y);
    CBook(char ch);
    CBook(const CBook &b); //CBook b2; CBook b1(b2);
    void display(void) const;
    void copy(const CBook &b2);
    void swap(CBook &b2);
    friend class CBooks;

    ~CBook(void);
    bool operator == (const CBook &b2) const;
    bool operator != (const CBook &b2) const;
    CBook & operator = (const CBook &b2);

    friend ostream & operator  << (ostream & john, const CBook &b); 
    friend void swapYear(CBook &b1, CBook &b2);

    friend ostream & operator  << (ostream & john, const CBooks &bc); 

  };


//////////////////////////////////////////////////////////////////////
//class CBooks
//////////////////////////////////////////////////////////////////////
class CBooks
  {
  private:
    int count;
    CBook *head;
    CBook *tail;
    CBook* addressByPos(int pos);
  public:
    CBooks(void);
    CBooks(int n);
    CBooks(const CBooks &bc);
    void display(void) const;
    void displayRev(void) const;
    void sortBubbleByYear(void);
    bool isSortedByYear(void) const;
    int add(char t[], char a[], int y);
    int remove(int loc); // Project #4
    ~CBooks(void);
    bool isEqualTo(const CBooks &bc2) const;
    bool operator ==(const CBooks &bc2) const;
    bool operator !=(const CBooks &bc2) const;

    friend ostream & operator  << (ostream & john, const CBooks &bc); 
    CBooks(char ch);
    void sortSelectionByYear(void);
    void sortBubbleByTitle(void);
    bool isSortedByTitle(void) const;

    void sortInsertionByYear(void);

    void removeAll(void);
    int add(const CBook &b);

    void displayRev(void);
    void shuffle(void);
    CBooks & operator = (const CBooks &bc2);

  };


//////////////////////////////////////////////////////////////////////
//test function prototypes
//////////////////////////////////////////////////////////////////////
void testOperatorInsertionCBooks(void);
void testAdd(void);
void testConstructorRandCBooks(void);
void testOperatorEqualCBooks(void);
void testOperatorNotEqualCBooks(void);
void testConstructorCopyCBooks(void);
void testDisplayRev(void);
void testShuffle(void);
void testAssignCBooks(void);


//////////////////////////////////////////////////////////////////////
//main function
//////////////////////////////////////////////////////////////////////
void main(void)
  {
  srand(time(NULL));
  //testOperatorInsertionCBooks();
  //testAdd();
  //testConstructorRandCBooks();
  //testOperatorEqualCBooks();
  //testOperatorNotEqualCBooks();
  //testConstructorCopyCBooks();
  //testDisplayRev();
  //testShuffle();
  testAssignCBooks();

  }


//overload = operator
// *this (n)        bc2 (m)
// n=0              m =0 
// n=m              m=n
// n=0              m>0
// n>0              m=0
// n>m              n>m
// n<m              n<m
CBooks & CBooks::operator = (const CBooks &bc2)
  {
  this->removeAll();

  CBook *p;

  p = bc2.head;
  while (p != NULL)
    {
    this->add(*p);
    p = p->next;
    }

  return *this;
  }


void testAssignCBooks(void)
  {
  CBooks bc1('r'), bc2('r'), bc3('r');
  cout << bc1;
  cout << bc2;
  cout << bc3;
  bc1 = bc2 = bc3;
  cout << "After bc1 = bc2 = bc3;\n";
  cout << bc1;
  cout << bc2;
  cout << bc3;
  }


void CBooks::shuffle(void)
  {
  if (count <=1) 
      return;

  int i, j;
  CBook *p, temp;

  for (i=1; i<=count*2000; i++)
    {
    j = rand()%count;
    p = this->addressByPos(j);

    temp = *p;
    *p = *head;
    *head = temp;
    }
  }


void testShuffle(void)
  {
  CBooks bc('r');
  cout << bc;
  cout << "******************SHUFFLED\n";
  bc.shuffle();
  cout << bc;
  }


//addressByPos
//returns address of the node at a given position (0, 1, 2, 3)
CBook* CBooks::addressByPos(int pos)
  {
  CBook *p;

  p = head;

  //advance p (i-1 times)
  for (int j=0; j<=pos-1; j++)
    p = p->next;

  return p;
  }


//////////////////////////////////////////////////////////////////////
//revDisplay
//////////////////////////////////////////////////////////////////////
void CBooks::displayRev(void)
  {
  CBook *p;
  int i;

  for (i=count; i>=1; i--)
    {
    p = addressByPos(i-1);
    cout << *p;
    }

  }


//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
void testDisplayRev(void)
  {
  cout << "TEST DISPLAY REVERSE\n";
  CBooks bc('r');
  cout << bc;
  cout << "IN REVERSE ORDER\n";
  bc.displayRev();
  }

/*
void CBooks::sortInsertionByYear(void)
  {
  int i, k;
  CBook temp;

  for (i=1; i<=count-1; i++)
    {
    if (books[i-1].year <= books[i].year)
        continue;
    temp = books[i];
    k = i;
    while (true)
      {
      books[k] = books[k-1];
      k--;

      if ((0 == k) || (books[k-1].year <= temp.year))
          {
          books[k] = temp;
          break;
          }
      }
    }
  }


//////////////////////////////////////////////////////////////////////
//test function for sortSelectionByYear
//////////////////////////////////////////////////////////////////////
void testSortInsertionByYear(void)
  {
  int n = rand()% (MAX_BOOKS + 1);

  CBooks bc(n);
  cout << "Original\n";
  bc.display();

  if (bc.isSortedByYear())
      cout << "SORTED\n";
    else
      cout << "NOT SORTED\n";

  bc.sortInsertionByYear();
  cout << "After sort\n";
  bc.display();

  if (bc.isSortedByYear())
      cout << "SORTED\n";
    else
      cout << "NOT SORTED\n";

  }


*/
  
/*
//////////////////////////////////////////////////////////////////////
//sortBubbleByTitle()
//////////////////////////////////////////////////////////////////////
void CBooks::sortBubbleByTitle(void)
  {
  bool sorted;
  int i;
  
  do 
    {
    sorted = true;
    for (i=0; i<=count-2; i++)
      {
      if (strcmp(books[i].title, books[i+1].title) > 0) 
        {
        books[i].swap(books[i+1]);
        sorted = false;
        }
      }
    }
    while (!sorted); 
  }


//////////////////////////////////////////////////////////////////////
//test function for sortByTitle
//////////////////////////////////////////////////////////////////////
void testSortByTitle(void)
  {
  int n = rand()% (MAX_BOOKS + 1);

  CBooks bc(n);
  cout << "Original\n";
  bc.display();

  if (bc.isSortedByTitle())
      cout << "SORTED\n";
    else
      cout << "NOT SORTED\n";

  bc.sortBubbleByTitle();
  cout << "Sorted\n";
  bc.display();

  if (bc.isSortedByYear())
      cout << "SORTED\n";
    else
      cout << "NOT SORTED\n";

  }


//////////////////////////////////////////////////////////////////////
//checks if sorted by title
//////////////////////////////////////////////////////////////////////
bool CBooks::isSortedByTitle(void) const
  {
  if (count <= 1)
      return true;

  for (int i=0; i<=count-2; i++)
    {
    if (strcmp(books[i].title, books[i+1].title) > 0)
        return false;
    }
  
  return true;
  }


*/


/*
void CBooks::sortSelectionByYear(void)
  {
  int n = count;
  int iMax, vMax, i;
  while (n > 1)
    {
    iMax = 0;
    vMax = books[iMax].year;
    for (i=1; i<=n-1; i++)
      {
      if (books[i].year > vMax)
          {
          iMax = i;
          vMax = books[i].year;
          }
      }

    books[iMax].swap(books[n-1]);
    n--;
    }
  }


//////////////////////////////////////////////////////////////////////
//test function for sortSelectionByYear
//////////////////////////////////////////////////////////////////////
void testSortSelectionByYear(void)
  {
  int n = rand()% (MAX_BOOKS + 1);

  CBooks bc(n);
  cout << "Original\n";
  bc.display();

  if (bc.isSortedByYear())
      cout << "SORTED\n";
    else
      cout << "NOT SORTED\n";

  bc.sortSelectionByYear();
  cout << "Sorted\n";
  bc.display();

  if (bc.isSortedByYear())
      cout << "SORTED\n";
    else
      cout << "NOT SORTED\n";

  }

*/

//////////////////////////////////////////////////////////////////////
//CBooks(char ch) constructor
//////////////////////////////////////////////////////////////////////
CBooks::CBooks(char ch)
  {
  head = tail = NULL;
  count = 0;

  if (('r' == ch) || ('R' == ch))
      {
      int n = rand()%(MAX_BOOKS+1);

      for (int i=0; i<n; i++)
        this->add(CBook('r'));
      }
  }


//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
void testConstructorRandCBooks(void)
  {
  CBooks bc1('r'), bc2('s');
  cout << bc1 << endl;
  cout << endl;
  cout << bc2 << endl;
  }


//////////////////////////////////////////////////////////////////////
//insertion operator overloaded for output
//////////////////////////////////////////////////////////////////////
ostream & operator  << (ostream & john, const CBooks &bc)
  {
  john << "Book Collection[" << bc.count << "]= \n";
  /*
  CBook *p;
  p = bc.head;
  while (p != NULL)
    {
    john << *p;
    p = p->next;
    }

  john << endl;
  */

  for (CBook *p = bc.head; p != NULL; p = p->next)
    john << *p;

  return john;
  }


//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
void testOperatorInsertionCBooks(void)
  {
  //CBooks bc1(5), bc2(5);

  CBooks bc1, bc2;

  cout << bc1 << bc2 << endl;
  }


//////////////////////////////////////////////////////////////////////
//compares for equality CBooks objects
//////////////////////////////////////////////////////////////////////
bool CBooks::operator ==(const CBooks &bc2) const
  {
  if (count != bc2.count)
      return false;

  CBook *p, *q;

  // if != overloaded for CBook
  for (p=head, q=bc2.head; p!=NULL; p=p->next, q=q->next)
    if (*p != *q)
      return false;

  return true;
  }


//////////////////////////////////////////////////////////////////////
//test operator equal
//////////////////////////////////////////////////////////////////////
void testOperatorEqualCBooks(void)
  {
    {
    CBooks bc1(5), bc2(5);
    cout << bc1;
    cout << bc2;

    if (bc1 == bc2)
        cout << "EQUAL\n";
      else
        cout << "NOT Equal\n";
    }

    {
    CBooks bc1, bc2;
    cout << bc1;
    cout << bc2;

    if (bc1 == bc2)
        cout << "EQUAL\n";
      else
        cout << "NOT Equal\n";

    CBooks bc3(bc1);
    if (bc1 == bc3)
        cout << "EQUAL\n";
      else
        cout << "NOT Equal\n";
    }
  }



//////////////////////////////////////////////////////////////////////
//compares for inequality CBooks objects
//////////////////////////////////////////////////////////////////////
bool CBooks::operator !=(const CBooks &bc2) const
  {
  return !((*this) == bc2);
  }


//////////////////////////////////////////////////////////////////////
//test operator not equal to
//////////////////////////////////////////////////////////////////////
void testOperatorNotEqualCBooks(void)
  {
    {
    CBooks bc1('r'), bc2('R');
    if (bc1 != bc2)
        cout << "Not EQUAL\n";
      else
        cout << "Equal\n";

    CBooks bc3(bc1);
    if (bc1 != bc3)
        cout << "NOT EQUAL\n";
      else
        cout << "Equal\n";
    }

    {
    CBooks bc1, bc2;
    if (bc1 != bc2)
        cout << "Not EQUAL\n";
      else
        cout << "Equal\n";

    /*
    CBooks bc3(bc1);
    if (bc1 != bc3)
        cout << "NOT EQUAL\n";
      else
        cout << "Equal\n";
    */
    }

  }


//////////////////////////////////////////////////////////////////////
//removeAll function
//////////////////////////////////////////////////////////////////////
void CBooks::removeAll(void)
  {
  while (head != NULL) 
    {
    tail=head; 
    head = head->next; 
    //cout << "deleting " << *tail;
    delete tail;
    }
  tail = NULL;
  count = 0;
  }


//////////////////////////////////////////////////////////////////////
//Cooks destructor 
//////////////////////////////////////////////////////////////////////
CBooks::~CBooks(void)
  {
  removeAll();
  }


//////////////////////////////////////////////////////////////////////
//add function
//////////////////////////////////////////////////////////////////////
int CBooks::add(const CBook &b)
  {
  CBook *p;
  p = new CBook;

  if (NULL == p) 
      return -1;

  strcpy(p->title, b.title);
  strcpy(p->author, b.author);
  p->year = b.year;
  p->next = NULL;

  if (NULL == head)
      head = tail = p;
    else
      {
      tail->next = p;
      tail = p;
      }

  count++;
  return count-1;
  }


//////////////////////////////////////////////////////////////////////
//add function
//////////////////////////////////////////////////////////////////////
int CBooks::add(char t[], char a[], int y)
  {
  CBook *p;
  p = new CBook;

  if (NULL == p) 
      return -1;

  strcpy(p->title, t);
  strcpy(p->author, a);
  p->year = y;
  p->next = NULL;

  if (NULL == head)
      head = tail = p;
    else
      {
      tail->next = p;
      tail = p;
      }

  count++;
  return count-1;
  }


//////////////////////////////////////////////////////////////////////
//test add
//////////////////////////////////////////////////////////////////////
void testAdd(void)
  {
  CBooks bc;
  cout << bc;
  for (int i=1; i<=5; i++)
    {
    cout << "+++++++++++++++++++++++++++\n";
    cout << bc.add("Title", "Author", i) << endl;
    cout << bc;
    }

  CBooks bc2;
  cout << bc2;
  for (int j=1; j<=5; j++)
    {
    cout << "+++++++++++++++++++++++++++\n";
    cout << bc2.add(CBook('r')) << endl;
    cout << bc2;
    }
  }


//////////////////////////////////////////////////////////////////////
//constructor CBooks()
//////////////////////////////////////////////////////////////////////
CBooks::CBooks(void)
  {
  count = 0;
  head = tail = NULL;
  }


//////////////////////////////////////////////////////////////////////
//constructor CBooks(n)
//////////////////////////////////////////////////////////////////////
CBooks::CBooks(int n)
  {
  if (n < 0) 
    n = 0;
  
  if (n > MAX_BOOKS)
    n = MAX_BOOKS;

  count = 0;
  head = tail = NULL;

  for (int i=0; i<n; i++)
    {
    this->add(CBook('r'));
    }
  }


//////////////////////////////////////////////////////////////////////
//constructor CBooks(CBooks bc)
//////////////////////////////////////////////////////////////////////
CBooks::CBooks(const CBooks &bc)
  {
  count =0;
  head = tail = NULL;
  CBook *p;

  for (p=bc.head; p!=NULL; p=p->next)
    this->add(*p);
  }


//////////////////////////////////////////////////////////////////////
//tes function for copy constructor
//////////////////////////////////////////////////////////////////////
void testConstructorCopyCBooks(void)
  {
  CBooks bc1('r'), bc2('r');

  cout << bc1 << bc2 << endl;
  CBooks bc3(bc2);
  cout << bc3;
  }


//////////////////////////////////////////////////////////////////////
//insertion operator overloaded for output
//////////////////////////////////////////////////////////////////////
ostream & operator  << (ostream & john, const CBook &b)
  {
  john << b.title ;
  john << ", " << b.author;
  john << ", " << b.year << endl;

  return john;
  }


//////////////////////////////////////////////////////////////////////
//test function for insertion operator
//////////////////////////////////////////////////////////////////////
void testOperatorInsertionCBook(void)
  {
  CBook b1('r'), b2('r');

  cout << b1 << b2 << endl;
  }


//////////////////////////////////////////////////////////////////////
//assign operator for CBook overloaded
//////////////////////////////////////////////////////////////////////
CBook & CBook::operator = (const CBook &b2)
  {
  strcpy(title, b2.title);
  strcpy(author, b2.author);
  year = b2.year;
  return *this;
  }


//////////////////////////////////////////////////////////////////////
//test function for assign operator
//////////////////////////////////////////////////////////////////////
void testOperatorAssignCBook(void)
  {
  CBook b1('r'), b2('r'), b3('R');
  cout << b1;
  cout << b2;
  cout << b3;

  b1 = b2 = b3;
  cout << b1;
  cout << b2;
  cout << b3;
  }


//////////////////////////////////////////////////////////////////////
//operator != overloaded
//////////////////////////////////////////////////////////////////////
bool CBook::operator != (const CBook &b2) const
  {
  return !(*this == b2);
  }


//////////////////////////////////////////////////////////////////////
//test operator !=
//////////////////////////////////////////////////////////////////////
void testOperatorNotEqualCBook(void)
  {
  CBook b1('r'), b2('r');
  cout << b1;
  cout << b2;
  if (b1 != b2)
      cout << "NOT EQUAL\n";
    else
      cout << "EQUAL\n";

  b2 = b1;
  cout << b1;
  cout << b2;
  if (b1 != b2)
      cout << "NOT EQUAL\n";
    else
      cout << "EQUAL\n";

  }


//////////////////////////////////////////////////////////////////////
//operator == overloaded
//////////////////////////////////////////////////////////////////////
bool CBook::operator == (const CBook &b2) const
  {
  if (strcmp(this->title, b2.title) != 0)
      return false;

  if (strcmp(this->author, b2.author) != 0)
      return false;

  if (this->year != b2.year)
      return false;

  return true;
  }


//////////////////////////////////////////////////////////////////////
//test operator ==
//////////////////////////////////////////////////////////////////////
void testOperatorEqualCBook(void)
  {
  CBook b1('r'), b2('r');
  cout << b1;
  cout << b2;
  if (b1 == b2)
      cout << "EQUAL\n";
    else
      cout << "NOT EQUAL\n";

  b2 = b1;
  cout << b1;
  cout << b2;
  if (b1 == b2)
      cout << "EQUAL\n";
    else
      cout << "NOT EQUAL\n";

  }


//////////////////////////////////////////////////////////////////////
//destructor CBook
//////////////////////////////////////////////////////////////////////
CBook::~CBook(void)
  {
  }


//////////////////////////////////////////////////////////////////////
//function to initialize the contents of CBook variable
//////////////////////////////////////////////////////////////////////
CBook::CBook(char t[], char a[], int y)
  {
  strcpy((*this).title, t);//strcpy(title, t);
  strcpy(this->author, a); //strcpy(author, a);
  year = y;
  }


//////////////////////////////////////////////////////////////////////
//function to initialize the contents of CBook variable
//////////////////////////////////////////////////////////////////////
CBook::CBook(void)
  {
  strcpy((*this).title, "-1");
  strcpy(this->author, "-1");
  year = -1;
  }


//////////////////////////////////////////////////////////////////////
//function to initialize the contents of CBook variable
//////////////////////////////////////////////////////////////////////
CBook::CBook(const CBook &b)
  {
  strcpy(title, b.title);
  strcpy(author, b.author);
  year = b.year;
  }


//////////////////////////////////////////////////////////////////////
//function to input the contents of BookType variable
//////////////////////////////////////////////////////////////////////
CBook::CBook(char ch)
  {
  if (('i' == ch) || ('I' == ch))
      {
      cout << "Title:  "; cin >> title;
      cout << "Author: "; cin >> author;
      cout << "Year:   "; cin >> year;
      }
    else if (('r' == ch) || ('R' == ch))
      {
      strcpy(title, testTitles[rand()%MAX_TITLES]);
      strcpy(author, testAuthors[rand()%MAX_AUTHORS]);
      year = testYears[rand()%MAX_YEARS];
      }
    else
      {
      strcpy((*this).title, "-1");
      strcpy(this->author, "-1");
      year = -1;
      }

  }