1. Trang chủ
  2. » Công Nghệ Thông Tin

A Complete Guide to Programming in C++ part 81 ppsx

10 290 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề A Complete Guide to Programming in C++ Part 81
Trường học University of Example
Chuyên ngành Computer Science
Thể loại Bài tập
Năm xuất bản 2023
Thành phố Example City
Định dạng
Số trang 10
Dung lượng 189,61 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

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 1

In 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 2

780 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 3

template <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 4

782 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 5

7 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 6

784 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 7

You 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 8

Memory 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 10

Example: #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

Ngày đăng: 06/07/2014, 17:21

TỪ KHÓA LIÊN QUAN