The rwith-outer simply tries to dispose of incoming messages as quickly as possible by sending each incoming message to the outgoing line with the shortest queue.. The class comprises an
Trang 1In data communications between two remote computers messages are transmitted via
multiple subnets En route to the target computers, so-called routers store these messages
in queues before transmitting them towards the target via the next available line The routers assume responsibility for route discovery, generally referring to complex address tables
There are various routing techniques, including a simple algorithm that can do
with-out address tables, the so-called Hot Potato Algorithm The rwith-outer simply tries to dispose
of incoming messages as quickly as possible by sending each incoming message to the outgoing line with the shortest queue
■ Define a container class VecQueue<T>, which is parameterized with a message typeTto represent this scenario The class comprises an array of queues of type
vector< queue<T> >and a data member used to store the current number of queues in the array
The constructor creates the number of empty queues passed to it as an argument for the array Additionally, you will need to declare the methods size(), empty(), push() and pop()
Overload the size() method in two versions: If no argument has been passed
to the method, it returns the current number of messages in all queues If an argu-mentiof type inthas been passed, the method returns the current number of messages in the i-th queue Additionally, overload the empty()and
empty(int i)methods, which return true, if all queues or the i-th queue are empty
Thepush()method uses the hot potato algorithm to append a message passed
to it at the end of the shortest queue
Thepop()andpop(int i)methods are used to simulate the assignment of messages to lines, that is retrieval and removal of messages from queues, in this exercise The method pop()retrieves the message at the top of a randomly selected queue and deletes it, returning the message The method pop(int i)
retrieves the message at the top of the i-th queue and deletes it, returning the message
■ To test your class, declare a container of the type VecQueue<int>in your
mainfunction A message is represented by a number Use a loop to insert ran-dom numbers between 0 and 99 into the container and relay some of them to the outside lines Then display the remaining messages on screen, as shown opposite,
by calling the pop(int i)method
Trang 2780 C H A P T E R 3 3 C O N T A I N E R S
Solution
// -// vecQueue.h
// Defining the Class Template VecQueue<T>
// to represent a vector of queues.
//
-#ifndef _VECQUEUE_H
#define _VECQUEUE_H
#include <vector>
#include <queue>
#include <cstdlib> // For srand(), rand()
#include <ctime> // For time() using namespace std;
template <class T>
class VecQueue {
private:
vector< queue<T> > v;
size_t sz; // Number of queues public:
VecQueue(size_t n);
size_t size() const; // Current number of all
// elements.
size_t size(int i) const // Number of elements in { return v[i].size(); } // the i-th queue.
bool empty() const { return size() == 0; } bool empty(int i) const { return size(i) == 0; } void push(const T& a); // Hot potato algorithm const T& pop(); // Removes the element at the
// beginning of a randomly // choosen queue.
const T& pop(int i); // Removes the element at the }; // beginning of the i-th queue template <class T>
VecQueue<T>::VecQueue( size_t n) // Constructor {
if(n > 0) v.resize(n);
sz = n;
srand(time(NULL));
}
Trang 3template <class T> // Current number of all elements
size_t VecQueue<T>::size() const
{
size_t count = 0;
for( int i=0; i < sz; ++i)
count += v[i].size();
return count;
}
template <class T> // To insert the argument into the
void VecQueue<T>::push(const T& a) // shortest queue
{
int small = 0; // To determine the
for(int i = 0; i < sz; i++) // shortest queue.
if( v[i].size() < v[small].size())
small = i;
v[small].push(a); // and insert there.
}
template <class T> // To retrieve and delete
const T& VecQueue<T>::pop() // an element in a randomly
{ // choosen queue.
static T temp;
int i, i0;
i = i0 = rand() % sz;
do
{
if(!v[i].empty()) // If i-th queue is not empty:
{ // To retrieve and delete the
temp = v[i].front(); // element at the beginning.
v[i].pop();
break;
}
i = (i+1) % sz; // Or else: Move to the next queue.
}
while( i != i0);
return temp;
}
template <class T> // To retrieve and delete
const T& VecQueue<T>::pop(int i) // an element in the
{ // i-th queue.
static T temp;
if( i >= 0 && i < sz) // If the index is okay:
{ // To retrieve the element
temp = v[i].front(); // at the beginning and
v[i].pop(); // to delete.
}
return temp;
}
#endif // _VECQUEUE_H
Trang 4782 C H A P T E R 3 3 C O N T A I N E R S
Solutions (continued)
// - // hotpot_t.cpp : Simulates the hot potato algorithm // using a vector of queues.
// -
#include <cstdlib> // For srand(), rand()
#include <ctime> // For time()
#include <iostream>
#include <iomanip>
using namespace std;
#include “vecQueue.h”
int main() {
const int nQueues = 9;
VecQueue<int> vq(9); // Vector of 9 queues cout << nQueues << “ queues have been created.”
<< endl;
srand(time(NULL));
cout << “\nThe queues will now be filled “
<< “using the hot potato algorithm.”
<< endl;
int i;
for(i = 0; i < 100; i++) // To insert 100 elements vq.push(rand()%100);
cout << “\nSome elements of randomly selected “
“queues are removed.”
<< endl;
for(i=0; i < 50; i++) // To remove 50 elements vq.pop();
cout << “\nTo output the queues:” << endl;
// To retrieve, remove for( i = 0; i < nQueues; ++i) // and display all { // remaining elements cout << “\n” << i+1 << “.Queue: “;
while( vq.size(i) > 0 ) {
cout << setw(4) << vq.pop(i);
} cout << endl;
} return 0;
}
Trang 57 8 3
This appendix contains
■ binary number representation
■ preprocessor directives
■ pre-defined standard macros
■ binding C functions
■ operator precedence table
■ ASCII Code table
■ screen control characters
appendix
Trang 6784 A P P E N D I X
The numbers used by a program can be divided into two groups depending on their type:
■ integers of the char,signed char,unsigned char,short,unsigned short,int,unsigned int,long, unsigned longtypes and
■ floating-point numbers of the float,double, and long doubletypes
Both integral and floating-point numbers are represented internally as binary numbers, that is, as sequences of 0 and 1 values However, the formats for representing integral and floating-point numbers differ Thus, the bit-pattern of an integer will be interpreted dif-ferently from that of a floating-point number by the computer
Representing Signed and Unsigned Integers
The binary format of integers is basically the same for the char,short, intandlong
types and differs only in
■ the number of bytes available for each type and
■ whether the number is interpreted as signed or unsigned
The bit-pattern of a positive integer can be represented as a base 2 power series The sign
bit0additionally indicates that the number is positive in the case of signedtypes The number 4can be represented by the following power series:
0*20 + 0*21 + 1*22 + 0*23 + 0*24
The binary representation of the number 4assigned chartype value (8 bits) is thus
as follows:
Two’s complement is used to represent a negative number, for example -4:
computed, that is, all the bits are inverted:
Sign bit
Trang 7You can also use two’s complement to compute the absolute value of a negative num-ber Two’s complement for -4yields a value of 4
Sign bits are not required for unsigned types The bit can then be used to represent further positive numbers, doubling the range of positive numbers that can be repre-sented
The following table contains the binary formats of signed and unsigned integral 8 bit values:
If the bit-pattern of a negative number is interpreted as an unsignednumber, the value
of the number changes The bit-pattern 1111 1100 of the number ⫺4 will thus yield the following unsignedvalue:
0*20 + 0*21 + 1*22 + 1*23 + 1*24 + 1*25 + 1*26 + 1*27
that is, the decimal number 252
Representing Floating-point Numbers
To represent a given floating-point number, x, the number is first broken down into a sign,v, a mantissa, m, and a power, exp,with a base of 2:
x = v * m * 2exp
0000 0000
0000 0001
0000 0010
0000 0011
0111 1101
0111 1110
0111 1111
1111 1100
1111 1101
1111 1110
1111 1111
1000 0000
1000 0001
Binary Signed decimal Unsigned decimal
.
.
0 1 2 3
125 126 127 –128 –127
–4 –3 –2 –1
.
.
128 129
252 253 254 255
.
0 1 2 3
125 126 127
Trang 8Memory for the values v, m, and exp is normally assigned in IEEE (Institute of Elec-tronics and Electronical Engineers) format The type float(32 bit) will thus be organ-ized as follows:
In this “normalized” form, floating-point numbers are unambiguous The mantissa, m, has
a value that is greater than or equal to 1 and less than 2, the only exception being x ==
0, where the mantissa is 0
The first digit of the mantissa is always 1 and need not be stored The power is stored
along with its bias A bias of 127applies for floattypes; thus a power eof a floating-point number is represented internally as e + 127
The memory reserved for the mantissa defines the accuracy, and the memory reserved for the power defines the range of values for the floating-point number
If platform-dependent ranges, such as the length of the mantissa or the smallest or largest value that can be represented, are significant in your programs, you can discover these ranges in the cfloator climits header files
You can use an instantiation of the numeric_limitsclass template for the type in question to query platform-dependent ranges by method calls
Bit position
786 A P P E N D I X
Trang 9■ PREPROCESSOR DIRECTIVES
The #define Directive
The#definedirective is used to define symbolic constants and macros
The preprocessor replaces name or name(parameterlist)withSubstituteText
throughout the whole program If SubstituteTextis not stated, the preprocessor will delete the symbolic constant or macro throughout the program code (see also Chapter 7,
“Symbolic Constants and Macros”.)
#define CLS cout << "\033[2J" // Macro
#define MAX(a,b) ((a)>(b) ? (a):(b))// Macro
The # Operator
A macro parameter in a substitute text can be preceded by the # operator (or stringizing
token) When the macro is called, the argument is set in quotes, that is, a string constant
is formed using the characters of the current argument
Example: #define TITLE(s) "**** " #s " *****"
The call
cout << TITLE(Catalog);
causes the preprocessor to expand the following string
"**** " "Catalog" " ****"
which is then concatenated to "**** Catalog ****"
The characters "and\are represented by \"and\\within an argument
"\\user\\" #logid "\\bin\\" #cmd
the string "\user\Smith\bin\games " is produced
The ## Operator
When a macro is defined, character sequences can be concatenated in the substitute
text The past token operator, ##, is used to this effect
When the macro is called, the parameter preceding or following the ## token is replaced by the appropriate argument Then the token and any leading or trailing white-space character is removed
Trang 10Example: #define debug(n) cout << "x" #n "=" << x ## n
Calling
debug(1);
will generate the statement
cout << "x1=" << x1;
The arguments of a macro are not parsed for symbolic constants or macros However, if the result of a concatenation is a symbolic constant or a macro, text replacement is again performed
The #undef Directive
To change the definition of a symbolic constant or a macro at program runtime, you must first remove the original definition To do so, the #undefdirective is used
Do not supply the parameter list for parameterized macros
You can then use the #definedirective to redefine the macro
#undef BUFSIZE
#define BUFSIZE 1024
The #include Directive
The#includedirective copies a file to a program The #includedirective is replaced
by the content of the file
Syntax: #include <filename>
#include "filename"
If the file name is surrounded by < and >, the file will only be looked up in the directo-ries defined by the environment variable (usually INCLUDE)
If the file name is stated in quotes the file will also be looked up in the current direc-tory first
The name filename can include a path In this case the file is only looked up in the directory stated
You can also supply the file name as a symbolic constant The substitute text must be
in quotes or square brackets in this case
788 A P P E N D I X