p03Books10
Home ] Up ]

 

//p03books10
//author
//date 07/19/2001
//date 07/18/2001
//date 07/17/2001
//date 07/16/2001
//date 07/15/2001
//date 07/13/2001
//date 07/11/2001
//date 07/10/2001
//date 07/09/2001
//date 07/06/2001
//date 07/05/2001

/*
Project#5
Overload assignment operator (=) for CBooks
testOperatorAssignCBooks()

*/

//////////////////////////////////////////////////////////////////////
//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 = 10;


//////////////////////////////////////////////////////////////////////
//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;
  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);
  };


//////////////////////////////////////////////////////////////////////
//class CBooks
//////////////////////////////////////////////////////////////////////
class CBooks
  {
  private:
    CBook books[MAX_BOOKS];
    int count;
  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);
  };



//////////////////////////////////////////////////////////////////////
//insertion sort by year
//////////////////////////////////////////////////////////////////////
/*
//version 0
for i=1 to n-1 
  insert a[i] at the right place
  end for


//version 1
for i=1 to n-1 
  //insert a[i] at the right place
  if a[i-1] <= a[i] then continue
  temp = a[i]
  k = i
  s1:
  a[k] = a[k-1]
  k = k-1

  if k = 0 then
      a[k] = temp
      continue
      end if

  if a[k-1] <= temp then
      a[k] = temp
      continue
    else
      goto s1

  end for


//version 2
for i=1 to n-1 
  //insert a[i] at the right place
  if a[i-1] <= a[i] then continue
  temp = a[i]
  k = i
  do forever
    a[k] = a[k-1]
    k = k-1

    if k = 0 then
        a[k] = temp
        continue with next i
        end if

    if a[k-1] <= temp then
        a[k] = temp
        continue with next i
        end if
    end do
  end for


//version 3
for i=1 to n-1 
  //insert a[i] at the right place
  if a[i-1] <= a[i] then continue
  temp = a[i]
  k = i
  do forever
    a[k] = a[k-1]
    k = k-1

    if (k = 0) or (a[k-1] <= temp) then
        a[k] = temp
        continue with next i
        end if
    end do
  end for

*/
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 = k-1;

      if ((k == 0) || (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 << "Sorted\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;
  }


//////////////////////////////////////////////////////////////////////
//selection sort by year
//////////////////////////////////////////////////////////////////////
/*

  find the the highest value
  swap it with the the last value
  decrease the count
continue until count = 1

n = count
do while n > 1
  iMax = 0;
  vMax = a[iMax]
  for i=1 to n-1
    if a[i] > vMax then
        iMax = i
        vMax = a[i]
        end if
    end for

  swap a[imax], a[n-1]
  n = n-1
  end do
*/
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";

  }


//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
void swapYear(CBook &b1, CBook &b2)
  {
  int temp;
  temp = b1.year;
  b1.year = b2.year;
  b2.year = temp;
  }


//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
CBooks::CBooks(char ch)
  {
  if (('r' == ch) || ('R' == ch))
      {
      count = rand()%(MAX_BOOKS+1);

      for (int i=0; i<count; i++)
        books[i] = CBook('r');
      }
    else
      count = 0;
  }


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

  }


//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
ostream & operator  << (ostream & john, const CBooks &bc)
  {
  for (int i=0; i<bc.count; i++)
    {
    john << i << ':';
    john << bc.books[i];
    }

  return john;
  }


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

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


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

  return john;
  }


//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
void testOperatorInsertionCBook(void)
  {
  CBook b1('r'), b2('r');

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


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


//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
void testOperatorAssignCBook(void)
  {
  CBook b1('r'), b2('r'), b3('R');
  b1.display();
  b2.display();
  b3.display();

  b1 = b2 = b3;
  b1.display();
  b2.display();
  b3.display();
  }


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


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

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

  }


//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
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;
  }


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

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

  }


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


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

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

    if (strcmp(this->books[i].author, bc2.books[i].author) != 0)
      return false;

    if (this->books[i].year != bc2.books[i].year)
      return false;
    }

  return true;
  }


//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
void testIsEqualTo(void)
  {
  CBooks bc1(5), bc2(5);
  if (bc1.isEqualTo(bc2))
      cout << "EQUAL\n";
    else
      cout << "NOT Equal\n";

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

  }


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

  /*
  for (int i= 0; i<=count-1; i++)
    {
    if (strcmp(this->books[i].title, bc2.books[i].title) != 0)
      return false;

    if (strcmp(this->books[i].author, bc2.books[i].author) != 0)
      return false;

    if (this->books[i].year != bc2.books[i].year)
      return false;
    }

  return true;
  */

  // if != overloaded for CBook
  for (int i=0; i<=count-1; i++)
    if (this->books[i] != bc2.books[i])
      return false;

  return true;
  }


//////////////////////////////////////////////////////////////////////
//test operator equal
//////////////////////////////////////////////////////////////////////
void testOperatorEqual(void)
  {
  CBooks bc1(5), bc2(5);
  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 testOperatorNotEqual(void)
  {
    {
    CBooks bc1(5), bc2(5);
    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";
    }

  }


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


//////////////////////////////////////////////////////////////////////
//main function
//////////////////////////////////////////////////////////////////////
void main(void)
  {
  srand(time(NULL));
  //CBook b1;
  //CBook b2("C++ in 10 Days", "John Smith", 2001);
  //b1.display();
  //b2.display();
  //CBook b3('i');
  //b3.display();
  //b1.copy(b2);
  //b1.display();
  //b1.swap(b2);
  //b1.display();
  //b2.display();
  //CBook b2[5];

  //testSortByYear();
  //testSortByTitle();
  //testSortSelectionByYear();
  testSortInsertionByYear();
  /*
  CBooks bc1(4);
  CBooks bc2(bc1);

  cout << sizeof(bc1) << endl;
  cout << sizeof(bc2) << endl;

  bc1.display();
  bc2.display();
  */

  //testAdd();
  /*
  CBooks *pbc;

  pbc = new CBooks;

  pbc = new CBooks;

  pbc->display();
  pbc->add("t1", "a1", 1);
  pbc->display();

  delete pbc;

  cout << "DOne\n";

  */
  //testIsEqualTo();
  //testOperatorEqual();
  //testOperatorNotEqual();
  //testOperatorEqualCBook();
  //testOperatorNotEqualCBook();
  //testOperatorAssignCBook();

  //testOperatorInsertionCBook();
  //testOperatorInsertionCBooks();
  //testConstructorRandCBooks();
  }


//////////////////////////////////////////////////////////////////////
//add function
//////////////////////////////////////////////////////////////////////
int CBooks::add(char t[], char a[], int y)
  {
  // POSSIBILITIES ON FRIDAY THE 13th
  // count == 0          : insert at place 0
  // count == MAX_BOOKS  : return -1
  // None of the above   : insert at count


  // count == MAX_BOOKS  : return -1
  if (MAX_BOOKS == count)
      return -1;

  // count == 0          : insert at place 0
  /*
  if (0 == count)
    {
    strcpy(books[0].title, t);
    strcpy(books[0].author, a);
    books[0].year = y;

    count++;
    return 0;
    }
  */

  // None of the above   : insert at count
  strcpy(books[count].title, t);
  strcpy(books[count].author, a);
  books[count].year = y;

  count++;
  return count-1;
  }


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


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


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

  count = n;
  for (int i=0; i<n; i++)
    {
    //get a random title
    strcpy(books[i].title, testTitles[rand()%MAX_TITLES]);
    //get a random author
    strcpy(books[i].author, testAuthors[rand()%MAX_AUTHORS]);
    //get a random year
    books[i].year = testYears[rand()%MAX_YEARS];
    }
  }


//////////////////////////////////////////////////////////////////////
//constructor CBooks(CBooks bc)
//////////////////////////////////////////////////////////////////////
CBooks::CBooks(const CBooks &bc)
  {
  count = bc.count;
  for (int i=0; i<count; i++)
    {
    //get a random title
    strcpy(books[i].title, bc.books[i].title);
    //get a random author
    strcpy(books[i].author, bc.books[i].author);
    //get a random year
    books[i].year = bc.books[i].year;
    }
  }


//////////////////////////////////////////////////////////////////////
//function to display the contents of BookType variable
//////////////////////////////////////////////////////////////////////
void CBook::display(void) const
  {
  cout << title ;
  cout << ", " << author;
  cout << ", " << year << endl;
  }


//////////////////////////////////////////////////////////////////////
//display()
//////////////////////////////////////////////////////////////////////
void CBooks::display(void) const
  {
  for (int i=0; i<count; i++)
    {
    cout << i << ':';
    books[i].display();
    }
  }


//////////////////////////////////////////////////////////////////////
//displayRev()
//////////////////////////////////////////////////////////////////////
void CBooks::displayRev(void) const
  {
  for (int i=count-1; i>=0; i--)
    {
    cout << i << ':';
    books[i].display();
    }
  }


//////////////////////////////////////////////////////////////////////
//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;
      }

  }


//////////////////////////////////////////////////////////////////////
//function to copy b2 to self/me
//////////////////////////////////////////////////////////////////////
void CBook::copy(const CBook &b2)
  {
  strcpy(author, b2.author);
  strcpy(title, b2.title);
  year = b2.year;
  }


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


//////////////////////////////////////////////////////////////////////
//test function for sortByYear
//////////////////////////////////////////////////////////////////////
void testSortByYear(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.sortBubbleByYear();
  cout << "Sorted\n";
  bc.display();

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

  }


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

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


//////////////////////////////////////////////////////////////////////
//swap(b)
//////////////////////////////////////////////////////////////////////
void CBook::swap(CBook &b2)
  {
  CBook temp;
  temp.copy(*this);
  this->copy(b2);
  b2.copy(temp);

  /*
  int tYear;
  char tTitle[TITLE_LEN+1];
  char tAuthor[AUTHOR_LEN+1];
  
  tYear = year;
  strcpy(tTitle, title);
  strcpy(tAuthor, author);

  ...
  */

  }