You are on page 1of 8

23

The shapes a bright

container can contain!

Standard
Template
Library (STL)

Theodore Roethke

Journey over all the universe

in a map.
Miguel de Cervantes

O! thou hast damnable

iteration, and art indeed
able to corrupt a saint.

OBJECTIVES
In this chapter you will learn:

William Shakespeare

That great dust heap called

history.

Augustine Birrell

reverse.

To be able to use the template STL containers, container

adapters and near containers.
To be able to program with the dozens of STL
algorithms.
To understand how algorithms use iterators to access the
elements of STL containers.
To become familiar with the STL resources available on
the Internet and the World Wide Web.

Attempt the end, and never

stand to doubt; Nothing's so
hard but search will nd it
out.
Robert Herrick

Chapter 23 Standard Template Library (STL)

Self-Review Exercises
State whether the following are true or false or fill in the blanks. If the answer is false, explain why,.
23.1
23.2
23.3

23.4
23.5
23.6

(T/F) The STL makes abundant use of inheritance and virtual functions.
ANS: False. These were avoided for performance reasons.

The two types of STL containers are sequence containers and

containers.

ANS: Associative.

,
,
The five main iterator types are
.
ANS: Input, output, forward, bidirectional, random access.

and

ANS: True.

(T/F) STL algorithms can operate on C-like pointer-based arrays.

ANS: True.

(T/F) STL algorithms are encapsulated as member functions within each container class.

ANS: False. STL algorithms are not member functions. They operate indirectly on contain-

ers, through iterators.

23.7 (T/F) The remove algorithm does not decrease the size of the vector from which elements
are being removed.
ANS: True.
23.8

The three STL container adapters are

ANS: stack, queue, priority_queue.

and

23.9

(T/F) Container member function end yields the position of the last element of the container.
ANS: False. It actually yields the position just after the end of the container.

23.10 STL algorithms operate on container elements indirectly, using

ANS: Iterators.
23.11 The sort algorithm requires a
ANS: Random-access.

iterator.

Exercises
23.12 Write a function template palindrome that takes a vector parameter and returns true or
false according to whether the vector does or does not read the same forward as backward (e.g., a
vector containing 1, 2, 3, 2, 1 is a palindrome, but a vector containing 1, 2, 3, 4 is not).
ANS:

1
2
3
4
5
6
7
8
9
10
11

// Exercise 23.12 Solution: Ex23_12.cpp

#include <iostream>
using std::cout;
#include <vector> // vector class-template definition
// function template palindrome definition
template < typename X >
bool palindrome( const std::vector< X > &vec )
{
std::vector< X >::const_reverse_iterator r = vec.rbegin();

Exercises
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

std::vector< X >::const_iterator i = vec.begin();

while ( r != vec.rend() && i != vec.end() )
{
if ( *r != *i ) // values are not equal
return false;
++r;
++i;
} // end while
return true; // the vector is a palindrome
} // end function palindrome
// function template printVector definition
template < typename Y >
void printVector( const std::vector< Y > &vec )
{
std::vector< Y >::const_iterator i;
for ( i = vec.begin(); i != vec.end(); ++i )
cout << *i << ' ';
} // end function palindrome
int main()
{
std::vector< int > iv;
std::vector< char > ic;
int x = 0;
for ( int i = 75; i >= 65; i-- )
{
iv.push_back( i );
ic.push_back( static_cast< char > ( i + x ) );
if ( i <= 70 )
x += 2;
} // end for
printVector( iv );
cout << ( palindrome( iv ) ? " is " : " is not " ) << "a palindrome\n";
printVector( ic );
cout << ( palindrome( ic ) ? " is " : " is not " ) << "a palindrome\n";
return 0;
} // end main

75 74 73 72 71 70 69 68 67 66 65 is not a palindrome
K J I H G F G H I J K is a palindrome

Chapter 23 Standard Template Library (STL)

23.13 Modify Fig. 23.40, the Sieve of Eratosthenes, so that, if the number the user inputs into the
program is not prime, the program displays the prime factors of the number. Remember that a
prime numbers factors are only 1 and the prime number itself. Every nonprime number has a
unique prime factorization. For example, the factors of 54 are 2, 3, 3 and 3. When these values are
multiplied together, the result is 54. For the number 54, the prime factors output should be 2 and 3.
ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

// Exercise 23.13 Solution: Ex23_13.cpp

#include <iostream>
using std::cin;
using std::cout;
using std::endl;
#include <iomanip>
using std::setw;
#include <cmath>
using std::sqrt;
#include <bitset> // bitset class definition
int main()
{
const int SIZE = 1024;
int i; // counter variable
int value;
int counter;
std::bitset< SIZE > sieve; // create bitset of 1024 bits
sieve.flip(); // flip all bits in sieve
sieve.reset( 0 ); // reset first bit (number 0)
sieve.reset( 1 ); // reset second bit (number 1)
// perform Sieve of Eratosthenes
int finalBit = sqrt( static_cast< double > ( sieve.size() ) ) + 1;
for ( i = 2; i < finalBit; i++ )
{
if ( sieve.test( i ) )
{
for ( int j = 2 * i; j < SIZE; j += i )
sieve.reset( j );
} // end if
} // end for
cout << "The prime numbers in the range 2 to 1023 are:\n";
// display prime numbers in range 2-1023
for ( i = 2, counter = 1; i < SIZE; i++ )
{
if ( sieve.test( i ) )
{
cout << setw( 5 ) << i;
if ( counter++ % 12 == 0 )

Exercises
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

cout << '\n';

} // end if
} // end for
cout << endl;
// get a value from the user to determine if it is prime
cout << "\nEnter a value from 1 to 1023 (-1 to end): ";
cin >> value;
while ( value != -1 )
{
if ( sieve[ value ] )
cout << value << " is a prime number\n";
else
{
cout << value << " is not a prime number\n"
<< "prime factor(s): ";
bool print = true;
for ( int f = 2; f < SIZE; )
{
if ( sieve.test( f ) && value % f == 0 )
{
if ( print )
cout << f << ' '; // output factor
value /= f; // modify value
if ( value <= 1 ) // time to stop
break;
print = false;
} // end if
else
{
f++; // move to next prime
print = true;
} // end else
} // end for
cout << '\n';
} // end else
cout << "\nEnter a value from 2 to 1023 (-1 to end): ";
cin >> value;
} // end while
return 0;
} // end main

The prime numbers in the range 2 to 1023 are:

2
3
5
7
11
13
17
19
23
41
43
47
53
59
61
67
71
73
97 101 103 107 109 113 127 131 137
157 163 167 173 179 181 191 193 197
227 229 233 239 241 251 257 263 269
283 293 307 311 313 317 331 337 347
367 373 379 383 389 397 401 409 419
439 443 449 457 461 463 467 479 487
509 521 523 541 547 557 563 569 571
599 601 607 613 617 619 631 641 643
661 673 677 683 691 701 709 719 727
751 757 761 769 773 787 797 809 811
829 839 853 857 859 863 877 881 883
919 929 937 941 947 953 967 971 977
1009 1013 1019 1021

29
79
139
199
271
349
421
491
577
647
733
821
887
983

31
83
149
211
277
353
431
499
587
653
739
823
907
991

37
89
151
223
281
359
433
503
593
659
743
827
911
997

Enter a value from 1 to 1023 (-1 to end): 8

8 is not a prime number
prime factor(s): 2
Enter a value from 2 to 1023 (-1 to end): 444
444 is not a prime number
prime factor(s): 2 3 37
Enter a value from 2 to 1023 (-1 to end): -1

23.14 Modify Exercise 23.13 so that, if the number the user inputs into the program is not prime,
the program displays the prime factors of the number and the number of times each prime factor
appears in the unique prime factorization. For example, the output for the number 54 should be
The unique prime factorization of 54 is: 2 * 3 * 3 * 3

ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

// Exercise 23.14 Solution: Ex23_14.cpp

#include <iostream>
using std::cin;
using std::cout;
using std::endl;
#include <iomanip>
using std::setw;
#include <cmath> // sqrt prototype
using std::sqrt;
#include <bitset>
int main()
{
const int SIZE = 1024;
int i;
int value;

Exercises
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

int counter;
std::bitset< SIZE > sieve; // create bitset of 1024 bits
sieve.flip(); // flip all bits in sieve
sieve.reset( 0 ); // reset first bit (number 0)
sieve.reset( 1 ); // reset second bit (number 1)
// perform Sieve of Eratosthenes
int finalBit = sqrt( static_cast< double > ( sieve.size() ) ) + 1;
for ( i = 2; i < finalBit; i++ )
{
if ( sieve.test( i ) )
{
for ( int j = 2 * i; j < SIZE; j += i )
sieve.reset( j );
} // end if
} // end for
cout << "The prime numbers in the range 2 to 1023 are:\n";
// display prime numbers in range 2-1023
for ( i = 2, counter = 1; i < SIZE; i++ )
{
if ( sieve.test( i ) )
{
cout << setw( 5 ) << i;
if ( counter++ % 12 == 0 )
cout << '\n';
} // end if
} // end for
cout << endl;
// get a value from the user to determine if it is prime
cout << "\nEnter a value from 1 to 1023 (-1 to end): ";
cin >> value;
while ( value != -1 )
{
if ( sieve[ value ] )
cout << value << " is a prime number\n";
else
{
cout << value << " is not a prime number\n"
<< "The unique prime factorization of " << value << " is: ";
for ( int f = 2; f < SIZE; )
{
if ( sieve.test( f ) && value % f == 0 )
{
cout << f; // output factor
value /= f; // modify value

8
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

if ( value <= 1 ) // time to stop

break;
cout << " * ";
} // end if
else
f++; // move to next prime
} // end for
cout << '\n';
} // end else
cout << "\nEnter a value from 2 to 1023 (-1 to end): ";
cin >> value;
} // end while
return 0;
} // end main

The prime numbers in the range 2 to 1023 are:

2
3
5
7
11
13
17
19
23
41
43
47
53
59
61
67
71
73
97 101 103 107 109 113 127 131 137
157 163 167 173 179 181 191 193 197
227 229 233 239 241 251 257 263 269
283 293 307 311 313 317 331 337 347
367 373 379 383 389 397 401 409 419
439 443 449 457 461 463 467 479 487
509 521 523 541 547 557 563 569 571
599 601 607 613 617 619 631 641 643
661 673 677 683 691 701 709 719 727
751 757 761 769 773 787 797 809 811
829 839 853 857 859 863 877 881 883
919 929 937 941 947 953 967 971 977
1009 1013 1019 1021

29
79
139
199
271
349
421
491
577
647
733
821
887
983

31
83
149
211
277
353
431
499
587
653
739
823
907
991

37
89
151
223
281
359
433
503
593
659
743
827
911
997

Enter a value from 1 to 1023 (-1 to end): 99

99 is not a prime number
The unique prime factorization of 99 is: 3 * 3 * 11
Enter a value from 2 to 1023 (-1 to end): 888
888 is not a prime number
The unique prime factorization of 888 is: 2 * 2 * 2 * 3 * 37
Enter a value from 2 to 1023 (-1 to end): -1