Nyhoff, ADTs, Data Structures and Problem
Solving with C++, Second Edition,
© 2005 Pearson Education, Inc. All rights reserved. 0-13-140909-3
Polynomial Class Declaration |
#ifndef POLYNOMIAL
#define POLYNOMIAL
template <typename CoefType>
class Polynomial
{
private:
/*** Term class ***/
class Term
{
public:
/*** Data members ***/
CoefType coef:
unsigned expo;
}; // end class Term
/*** Node Class ***/
class Node
{
public:
Term data;
Node * next;
// -- Node constructor
// creates a node with given initial values
Node (CoefType co = 0, int x = 0, Node * ptr = 0)
{
data.coef = co;
data.expo = ex;
next = ptr;
}
}; // end of Node class
public:
/*** Function members ***/
// operations on polynomials
private:
/*** Data members ***/
int myDegree;
NodePointer myTerms; // a linked list with head node;
// its ElementType is Term
}; // end of Polynomial class template
#endif
|
Addition Operator for Polynomial Class |
Polynomial <CoefType> operator+(
const Polynomial <CoefType> & secondPoly)
/*------------------------------------------------
Precondition: None
Postcondition: A polynomial representing the sum of
the current polynomial and secondPoly is returned.
--------------------------------------------------*/
{
Polynomial <CoefType> polySum;
Poly<CoefType>::NodePointer // pointers to
ptra = myTerms->next. // thru 1st poly.
ptrb = secondPoly.myTerms->next, // 2nd poly,
ptrc = polySum.myTerms; // sum poly
int degree = 0;
while (ptra != 0 || ptrb != 0) // More nodes in
{ // one of polys
if ((ptrb == 0) || // Copy from 1st poly
(ptra != 0 && ptra->data.expo < ptrb->data.expo))
{
ptrc->next = new Polynomial<coefTpe>::
Node(ptra->data.coef, ptra->data.expo);
degree = ptra->data.expo;
ptra = ptra->next;
ptrc = ptrc->next;
}
else if ((ptra == 0) || // Copy from 2nd poly
(ptrb != 0 && ptrb->expo < ptra<expo))
{
ptrc->nwext = new Polynomial<CoefType>::
Node(ptrb->data.coef, ptrb->data.expo);
degree = ptrb->data.expo;
ptrb = ptrb->next;
ptrc = ptrc->next;
}
else // exponents match
{
CoefType sum = ptra->data.coef + ptrb.data.coef;
if (sum != 0) // Nonzero sum --
{ // add to sum poly
ptrc->next = new Polynomial<CoefType>::
Node(sum, ptra->data.expo);
degree = ptra->data.expo;
ptrc = ptrc->next;
}
ptra = ptra->next; // Move along in
ptrb = ptrb->next; // 1st and 2nd lists
}
}
sumPoly.myDegree = degree; // Wrapup
return sumPoly;
}
|
Figure 11.1 Demonstration of list Operations |
#include <iostream>
#include <list>
#include <algorithm>
using namespace std;
//--- Overload output operator for list<T>
template <typename T>
ostream & operator<<(ostream & out, const list<T> & aList)
{
for (list<T>::const_iterator it = aList.begin(); it != aList.end(); it++)
out << *it << " ";
return out;
}
int main()
{
// Constructors
//=============
list<int> la, lb(4, 111), lc(6);
int array[] = {2, 22, 222,2222};
list<int> ld(array, array + 4);
cout << "la: " << la << " -- size = " << la.size() << endl;
cout << "lb: " << lb << " -- size = " << lb.size() << endl;
cout << "lc: " << lc << " -- size = " << lc.size() << endl;
cout << "ld: " << ld << " -- size = " << ld.size() << endl;
// Assignment
//===========
cout << "\nAssignments la = ld and lc = ld:" << endl;
la = ld;
lc = ld;
cout << "la = " << la << " -- size = " << la.size() << endl;
cout << "lc = " << lc << " -- size = " << lc.size() << endl;
// Ways to insert into a list
//===========================
cout << "\nInserts in lb:\n";
list<int>::iterator i;
i = lb.begin();
i++; i++;
lb.insert(i, 66666);
cout << lb << endl;
lb.insert(i,3, 555);
cout << lb << endl;
lb.insert(i, array, array + 3);
cout << lb << endl;
lb.push_back(888);
lb.push_front(111);
cout << lb << endl;
// Ways to delete from a list
//===========================
cout << "\nErases in lb:\n";
i = find(lb.begin(), lb.end(), 66666); // find is an algorithm
if (i != lb.end())
{
cout << "66666 found -- will erase it\n";
lb.erase(i);
}
else
cout << "66666 not found\n";
cout << lb << endl;
i = lb.begin(); i++;
list<int>::iterator j = lb.end();
--j; --j; i = --j; i --; i--;
lb.erase(i,j);
cout << lb << endl;
lb.pop_back();
lb.pop_front();
cout << lb << endl;
// Reversing a list
//=================
cout << "\nReverse ld:\n";
ld.reverse();
cout << ld << endl;
// Sorting a list
//===============
cout << "\nSort lb and ld:\n";
lb.sort();
ld.sort();
cout << "lb: " << lb << "\nld: " << ld << endl;
// Merging two lists
//==================
cout << "\nMerge lb and ld:\n";
lb.merge(ld);
cout << "lb: " << lb << endl;
cout << "ld: " << ld << endl;
// Splicing a list into another list
//==================================
cout << "\nSplice lc into la at second position:\n";
i=la.begin(); i++;
la.splice(i, lc);
cout << "la: " << la << endl;
cout << "lc: " << lc << endl;
// Global removal of a value
//==========================
cout << "\nRemove 22s from la:\n";
la.remove(22);
cout << la << endl;
// Eliminating duplicates
//=======================
cout << "\nUnique applied to lb:\n";
lb.unique();
cout << lb << endl;
}
|
Figure 11.2 Internet Addresses |
/*-- Class AddressCounter --------------------------------------------------
Models occurrences of IP addresses in a login file.
-------------------------------------------------------------------------*/
#include <string>
#include <iostream>
using namespace std;
class AddressCounter
{
public:
/*** Function Members ***/
AddressCounter();
/*------------------------------------------------------------------------
Precondition: None.
Postcondition: myAddress is an empty string and myCount is 0.
-----------------------------------------------------------------------*/
void read(istream & in);
/*------------------------------------------------------------------------
Precondition: istream in is open.
Postcondition: Value for AddressCounter has been read from in.
-----------------------------------------------------------------------*/
void print(ostream & out) const;
/*------------------------------------------------------------------------
Precondition: ostream out is open.
Postcondition: Value of AddressCounter has been output to out.
-----------------------------------------------------------------------*/
void tally();
/*------------------------------------------------------------------------
Precondition: None.
Postcondition: myCount has been incremented by 1.
-----------------------------------------------------------------------*/
bool operator==(const AddressCounter & addr);
/*------------------------------------------------------------------------
Precondition: None.
Postcondition: True is returned if this address and addr have the
same address, and false otherwise.
-----------------------------------------------------------------------*/
private:
/*** Data Members ***/
string myAddress;
int myCount;
}; // end of class declaration
//--- Definition of constructor
inline AddressCounter::AddressCounter()
: myAddress(""), myCount(0)
{ }
//--- Definition of read()
inline void AddressCounter::read(istream & in)
{
in >> myAddress;
myCount = 1;
}
//--- Definition of print()
inline void AddressCounter::print(ostream & out) const
{
out << myAddress << "\t occurs " << myCount << " times\n";
}
//--- Definition of tally()
inline void AddressCounter::tally()
{
myCount++;
}
//--- Definition of == operator
inline bool AddressCounter::operator==(const AddressCounter & addr)
{
return myAddress == addr.myAddress;
}
/*--------------------------------------------------------------------------
Program to read IP addresses from a file and produce a list of distinct
addresses and a count of how many times each appeared in the file.
-------------------------------------------------------------------------*/
#include <fstream>
#include <cassert>
#include <list>
#include <algorithm>
int main()
{
string fileName; // name of file of IP addresses
ifstream inStream; // open stream to file of addresses
cout << "Enter name of file containing IP addresses: ";
cin >> fileName;
inStream.open(fileName.data());
assert(inStream.is_open());
list<AddressCounter> addressList; // list of AddressCounter objects
AddressCounter addr;
for (;;) // loop:
{
addr.read(inStream); // read an address
if (inStream.eof()) break; // if eof, quit
list<AddressCounter>::iterator // check if addr already in list
it = find(addressList.begin(), addressList.end(), addr);
if (it != addressList.end()) // found
(*it).tally(); // increment its count
else
addressList.push_back(addr); // else add it to the list
} // end loop
// output the list
cout << "\nList of addresses:\n\n";
for (list<AddressCounter>::iterator it = addressList.begin();
it != addressList.end(); it++)
(*it).print(cout);
}
|
Figure 11.3A BigInt.h |
/*-- BigInt.h -------------------------------------------------------------
This header file defines the data type BigInt for processing
integers of any size.
Basic operations are:
Constructor
+: Addition operator
read(): Read a BigInt object
display(): Display a BigInt object
<<, >> : Input and output operators
-------------------------------------------------------------------------*/
#include <iostream>
#include <iomanip> // setfill(), setw()
#include <list>
#ifndef BIGINT
#define BIGINT
const int DIGITS_PER_BLOCK = 3;
class BigInt
{
public:
/******** Function Members ********/
/***** Constructor *****/
// Let the list<short int> constructor take care of this.
/***** read *****/
void read(istream & in);
/*-----------------------------------------------------------------------
Read a BigInt.
Precondition: istream in is open anc cdntains blocks of nonnegative
integers having at most DIGITS_PER_BLOCK digits per block.
Postcondition: Blocks have been removed from in and added to myList.
-----------------------------------------------------------------------*/
/***** display *****/
void display(ostream & out) const;
/*-----------------------------------------------------------------------
Display a BigInt.
Precondition: ostream out is open.
Postcondition: The large integer represented by this BigInt object
has been formatted with the usual comma separators and inserted
into ostream out.
------------------------------------------------------------------------*/
/***** addition operator *****/
BigInt operator+(BigInt addend2);
/*------------------------------------------------------------------------
Add two BigInts.
Precondition: addend2 is the second addend.
Postcondition: The BigInt representing the sum of the large integer
represented by this BigInt object and addend2 is returned.
------------------------------------------------------------------------*/
private:
/*** Data Members ***/
list<short int> myList;
}; // end of BigInt class declaration
//------ Input and output operators
inline istream & operator>>(istream & in, BigInt & number)
{
number.read(in);
return in;
}
inline ostream & operator<<(ostream & out, const BigInt & number)
{
number.display(out);
return out;
}
#endif
|
Figure 11.3B BigInt.cpp |
/*-- BigInt.cpp-------------------------------------------------------------
This file implements BigInt member functions.
--------------------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include "BigInt.h"
//--- Definition of read()
void BigInt::read(istream & in)
{
static bool instruct = true;
if (instruct)
{
cout << "Enter " << DIGITS_PER_BLOCK << "-digit blocks, separated by "
"spaces.\nEnter a negative integer in last block to signal "
"the end of input.\n\n";
instruct = false;
}
short int block;
const short int MAX_BLOCK = (short) pow(10.0, DIGITS_PER_BLOCK) - 1;
for (;;)
{
in >> block;
if (block < 0) return;
if (block > MAX_BLOCK)
cerr << "Illegal block -- " << block << " -- ignoring\n";
else
myList.push_back(block);
}
}
//--- Definition of display()
void BigInt::display(ostream & out) const
{
int blockCount = 0;
const int BLOCKS_PER_LINE = 20; // number of blocks to display per line
for (list<short int>::const_iterator it = myList.begin(); ; )
{
out << setfill('0');
if (blockCount == 0)
out << setfill(' ');
if (it == myList.end())
return;
out << setw(3) << *it;
blockCount++ ;
it++;
if (it != myList.end())
{
out << ',';
if (blockCount > 0 && blockCount % BLOCKS_PER_LINE == 0)
out << endl;
}
}
}
//--- Definition of operator+()
BigInt BigInt::operator+(BigInt addend2){
BigInt sum;
short int first, // a block of 1st addend (this object)
second, // a block of 2nd addend (addend2)
result, // a block in their sum
carry = 0; // the carry in adding two blocks
list<short int>::reverse_iterator // to iterate right to left
it1 = myList.rbegin(), // through 1st list, and
it2 = addend2.myList.rbegin(); // through 2nd list
while (it1 != myList.rend() || it2 != addend2.myList.rend())
{
if (it1 != myList.rend())
{
first = *it1;
it1++ ;
}
else
first = 0;
if (it2 != addend2.myList.rend())
{
second = *it2;
it2++ ;
}
else
second = 0;
short int temp = first + second + carry;
result = temp % 1000;
carry = temp / 1000;
sum.myList.push_front(result);
}
if (carry > 0)
sum.myList.push_front(carry);
return sum;
}
|
Figure 11.4 Driver Program for BigInt Class |
//--- Program to test BigInt class.
#include <iostream>
using namespace std;
#include "BigInt.h"
int main()
{
char response;
do
{
BigInt number1, number2;
cout <<"Enter a big integer:\n";
cin >> number1;
cout <<"Enter another big integer:\n";
cin >> number2;
cout << "The sum of\n\t"
<< number1 << "\nand\n\t" << number2
<< "\nis\n\t" << number1 + number2 << endl;
cout << "\nAdd more integers (Y or N)? ";
cin >> response;
}
while (response == 'y' || response == 'Y');
}
|
Figure |
|
|
Figure |
|
|
Figure |
|
|
Figure |
|
|
Figure |
|
|
Figure |
|
|
Figure |
|
|
Figure |
|
|
Figure |
|
|
Figure |
|
|
Figure |
|
|
Figure |
|
|