Tải bản đầy đủ (.pdf) (10 trang)

A Complete Guide to Programming in C++ part 77 doc

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (120.03 KB, 10 trang )

EXERCISES

739
Exercise 1
■ Define a function template interpolSearch() that looks up a given ele-
ment in a sorted, numeric array.The array elements are of the same type
as the template parameter
T.
The function template has three parameters—the value searched for of
type
T, a pointer to the first array element, and the number of array ele-
ments.
The function template returns the index of the first element in the array
that corresponds to the searched for value, or –1 if the value cannot be
found in the array.
Implement the function template. Use the technique described opposite
as your algorithm for the interpolation search. Store the function tem-
plate definition in the header file
search.h.
■ Define a function template, insertionSort(), which sorts a numeric
array in ascending order.The array elements are of the type of the tem-
plate parameter
T.
The function template has two parameters—a pointer to the first array
element, and the number of array elements.There is no return value.
■ Define a function template display() to display a numeric array on
screen.
The function template has two parameters—a pointer to the first array
element and the number of array elements.There is no return value.
■ Use the function templates interpolSearch(), insertionSort(), and
display() to define template functions for double and short types.To


do so, define an array of
double values and an array with short values.
Write a
main function that creates and calls each template function
insertionSort() for the int and double types.Then display the
sorted arrays.
Add a call to each template function
search() in your main function.
Call
search() passing values that exist and do not exist in the array.
740

CHAPTER 32 TEMPLATES
class FloatArr // Without conversion functions
{
private:
float* arrPtr; // Dynamic member
int max; // Maximum number, without having
// to reallocate storage.
int cnt; // Current number of elements
void expand( int new Size); // Function to help
// enlarge the array.
public:
FloatArr( int n = 256 );
FloatArr( int n, float val);
FloatArr(const FloatArr& src);
~FloatArr();
FloatArr& operator=( const FloatArr& );
int length() const { return cnt; }
float& operator[](int i) throw(BadIndex);

float operator[](int i) const throw(BadIndex);
void append( float val);
void append( const FloatArr& v);
FloatArr& operator+=( float val)
{
append( val); return *this;
}
FloatArr& operator+=( const FloatArr& v)
{
append(v); return *this;
}
void insert( float val, int pos) throw(BadIndex);
void insert( const FloatArr& v, int pos )
throw(BadIndex);
void remove(int pos) throw(BadIndex);
friend ostream& operator<<( ostream& os,
const FloatArr& v);
};
Exercises
The class FloatArr (as defined in Chap. 28, Ex. 1)
EXERCISES

741
Exercise 2
Define a class template Array<T, n> to represent an array with a maximum of
n elements of type T.Attempting to address an array element with an invalid
index should lead to an exception of the
BadIndex (defined previously) error
class being thrown. If there is no space left to insert an element in the array, an
exception of the

OutOfRange type should be thrown.
■ First define the error class OutOfRange without any data members. Use
the error class
BadIndex, which was defined in Exercise 1 of Chapter 28.
■ Change the existing FloatArr class into a class template, Array<T, n>.
Use
255 as the default value for the parameter n of the class template.
This allocates memory for the array statically. Now define a default con-
structor and a constructor that initializes a given number of array ele-
ments with a given value.You do not need to define a copy constructor, a
destructor, or an assignment operator.
As access methods define the
size() and the length() methods, the
size() method returns the maximum number of array elements, that
is,
n; the length() method returns the current number of elements in
the array.
Also define methods for inserting and deleting elements like those
defined for the
FloatArr class.The methods have a void return type and
can throw exceptions of type
BadIndex and/or OutOfRange.
Additionally overload the index and shift operators
<<.The subscript
operator throws
BadIndex type exceptions.
■ Test the class template Array<T,n> for double and int types first.
Define arrays of the appropriate types, then insert and delete elements in
the arrays. Output all the elements of the array.
■ Modify the test program by adding an array for objects of a class type.

Use the
DayTime class from Exercise 1, Chapter 19 for this purpose.
Test the array template by defining an array with 5
DayTime class objects
and inserting a few objects.Then display all the objects on screen.
solutions
742

CHAPTER 32 TEMPLATES

SOLUTIONS
Exercise 1
//
// interpol.cpp : Template function interpolSearch()
//
#include <iostream>
using namespace std;
template <class T>
long interpolSearch(const T& key, T* vp, int len)
{
int expect, begin = 0, end = len - 1;
double temp;
if( end < 0 // Array is empty or
|| key > vp[end] // or key is out of
|| key < vp[begin] ) // range
return -1;
while( begin <= end )
{
if(key > vp[end] || key < vp[begin] ) // Key is not
return -1; // in range.

temp = (double)(key - vp[begin])
/ (vp[end]-vp[begin]);
temp = temp * (end - begin) +0.5;
expect = begin + (int)temp;
if( vp[expect] == key ) // Key found?
return expect;
if( vp[expect] > key)
end = expect - 1;
else begin = expect+1;
}
return -1;
}
template <class T>
void insertionSort( T* vp, int len)
{
T temp;
for( int i=0; i < len; i++)
{
temp = vp[i]; // Take element out.
int j; // Shift greater elements up:
for( j = i-1; j >= 0 && vp[j] > temp; j )
vp[j+1] = vp[j];
vp[j+1] = temp; // Insert.
}
}
SOLUTIONS

743
template <class T>
void display(T* vp, int len)

{
cout << "\n\nThe array: " << endl;
for(int i = 0; i < len; i++)
{
cout << vp[i] << " ";
if( (i+1)%10 == 0)
cout << endl;
}
cout << endl; cin.get();
}
// Two arrays for testing:
short sv[5] = { 7, 9, 2, 4, 1};
double dv[5] = { 5.7, 3.5, 2.1, 9.4, 4.3 };
int main()
{
cout << "\nInstantiation for type short: " << endl;
display(sv, 5);
insertionSort(sv, 5);
cout << "\nAfter sorting: ";
display(sv, 5);
short key;
cout << "\nArray element? "; cin >> key; cin.sync();
int pos = interpolSearch(key, sv, 5);
if( pos != -1)
cout << "\nfound!" << endl, cin.get();
else
cout << "\nnot found!" << endl, cin.get();
//
cout << "\nInstantiation for type double: " << endl;
display(dv, 5);

insertionSort(dv, 5);
cout << "\nAfter sorting: ";
display(dv, 5);
double dkey;
cout << "\nArray element? "; cin >> dkey; cin.sync();
pos = interpolSearch(dkey, dv, 5);
if( pos != -1)
cout << "\nfound!" << endl, cin.get();
else
cout << "\nnot found!" << endl, cin.get();
return 0;
}
744

CHAPTER 32 TEMPLATES
Exercise 2
//
// array.h
// Use of class templates to represent arrays.
//
#ifndef _ARRAY_H_
#define _ARRAY_H_
#include <iostream>
#include <iomanip>
using namespace std;
class BadIndex
{
private:
int index;
public:

BadIndex(int i):index(i){}
int getBadIndex() const { return index; }
};
class OutOfRange { /* Without data members*/ };
template <class T, int n = 256>
class Array
{
private:
T arr[n]; // The array
int cnt; // Current number of elements
public:
Array( ){ cnt = 0;}
Array(int n, const T& val );
int length() const { return cnt; }
int size() const { return n; }
T& operator[](int i) throw(BadIndex)
{
if( i < 0 || i >= cnt ) throw BadIndex(i);
return arr[i];
}
const T& operator[](int i) const throw(BadIndex)
{
if( i < 0 || i >= cnt ) throw BadIndex(i);
return arr[i];
}
SOLUTIONS

745
Array& operator+=( float val) throw(OutOfRange)
{

append( val); return *this;
}
Array& operator+=(const Array& v) throw(OutOfRange)
{
append(v); return *this;
}
void append( T val) throw(OutOfRange);
void append( const Array& v) throw(OutOfRange);
void insert( T val, int pos)
throw(BadIndex, OutOfRange);
void insert( const Array& v, int pos )
throw(BadIndex, OutOfRange);
void remove(int pos) throw(BadIndex);
};
template <class T, int n >
Array<T,n>::Array(int m, const T& val )
{
cnt = m;
for(int i=0; i < cnt; i++ )
arr[i] = val;
}
template <class T, int n >
void Array<T,n>::append( T val) throw(OutOfRange)
{
if( cnt < n)
arr[cnt++] = val;
else
throw OutOfRange();
}
template <class T, int n >

void Array<T,n>::append( const Array<T,n>& v) throw(OutOfRange)
{
if( cnt + v.cnt > n) // Not enough space.
throw OutOfRange();
int count = v.cnt; // Necessary if
// v == *this
for( int i=0; i < count; ++i)
arr[cnt++] = v.arr[i];
}
746

CHAPTER 32 TEMPLATES
template <class T, int n >
void Array<T,n>::insert( T val, int pos)
throw(BadIndex, OutOfRange)
{ insert( Array<T,n>(1,val), pos);
}
template <class T, int n >
void Array<T,n>::insert( const Array<T,n>& v, int pos )
throw(BadIndex, OutOfRange)
{
if( pos < 0 || pos >= cnt)
throw BadIndex(); // Invalid position.
if( n < cnt + v.cnt)
throw OutOfRange();
int i;
for( i = cnt-1; i >= pos; i) // Shift up
arr[i+v.cnt] = arr[i]; // starting at pos.
for( i = 0; i < v.cnt; ++i) // Fill the gap.
arr[i+pos] = v.arr[i];

cnt = cnt + v.cnt;
}
template <class T, int n >
void Array<T,n>::remove(int pos) throw(BadIndex)
{
if( pos >= 0 && pos < cnt)
{
for( int i = pos; i < cnt-1; ++i)
arr[i] = arr[i+1];
cnt;
}
else throw BadIndex(pos);
}
template <class T, int n >
ostream& operator<<(ostream& os, const Array<T,n>& v)
{
int w = os.width(); // Save the field width
for( int i = 0; i < v.cnt; ++i)
{
os.width(w); os << v.arr[i];
}
os << endl;
return os;
}
#endif
SOLUTIONS

747
//
// DayTime.h

// Class DayTime with relational operators,
// the operators ++ and (prefix and postfix),
// and the operators << and >> for I/O.
//
// The same as in Chapter 19.
//
// Array_t.cpp
// Testing class templates Array<T,n>.
//
#include "array.h"
#include "DayTime.h"
#include <cstdlib>
#include <iostream>
#include <iomanip>
using namespace std;
typedef Array<int, 100> IntArr;
typedef Array<double> DoubleArr;
typedef Array<DayTime, 5> DayTimeArr;
int main()
{
try
{
const DoubleArr vd(10, 9.9);
DoubleArr kd;
cout << "\nThis is the constant array of doubles: \n";
cout << setw(8) << vd;
kd = vd;
cout << "\nAn array of doubles after the assignment: "
<< endl;
cout << setw(8) << kd;

kd.remove(3); // Delete the element at
// position 3.
kd.append(10.0); // Add a new element.
kd.append(20.0); // And repeat!
cout << "\nThis is the modified array: "
<< endl;
cout << setw(8) << kd;
748

CHAPTER 32 TEMPLATES
IntArr vi;
int i;
for(i=0; i < 10; i++)
vi.append(rand()/100);
cout << "\nThis is the array of int values: \n";
cout << setw(12) << vi;
vi += vi;
cout << "\nAnd append: \n";
cout << setw(12) << vi;
IntArr ki(vi);
cout << "\nThis is the copy of the array: \n";
cout << setw(12) << ki;
DayTimeArr vt; // Array of DayTime objects.
DayTime temp;
for(i=0; i < 3; i++)
{
if( !(cin >> temp))
break;
vt.append(temp);
}

cout << "\nThe array with objects of type DayTime:\n";
for(i=0; i < 3; i++)
cout << setw(20) << vt[i] << endl;
}
catch(BadIndex& err)
{
cerr << "\nIndex " << err.getBadIndex()
<< " invalid";
exit(1);
}
catch(OutOfRange& )
{
cerr << "\nArray is full!";
exit(2);
}
return 0;
}

×