Algorithms. McGraw-Hill The Complete Reference Fourth Edition
Below you will find brief information for C++ programming book The Complete Reference Fourth Edition. This book covers the International Standard for C++, including keywords, syntax, and libraries. It includes advanced features such as overloading, inheritance, virtual functions, namespaces, templates, the STL, and RTTI. It works with all C++ compilers, including Visual C++.
Advertisement
Advertisement
664
C + + : T h e C o m p l e t e R e f e r e n c e if(p != directory.end()) cout << "Phone number: " << p->second.get(); else cout << "Name not in directory.\n";
} return 0;
Here is a sample run:
Enter name: Rachel
Phone number: 555-0809.
In the program, each entry in the map is a character array that holds a null- terminated string. Later in this chapter, you will see an easier way to write this program that uses the standard string type.
Algorithms
As explained, algorithms act on containers. Although each container provides support for its own basic operations, the standard algorithms provide more extended or complex actions. They also allow you to work with two different types of containers at the same time. To have access to the STL algorithms, you must include <algorithm> in your program.
The STL defines a large number of algorithms, which are summarized in Table 24-5.
All of the algorithms are template functions. This means that they can be applied to any type of container. All of the algorithms in the STL are covered in Part Four. The following sections demonstrate a representative sample.
Counting
One of the most basic operations that you can perform on a sequence is to count its contents. To do this, you can use either count( ) or count_if( ). Their general forms are shown here: template <class InIter, class T> ptrdiff_t count(InIter start, InIter end, const T &val); template <class InIter, class UnPred> ptrdiff_t count_if(InIter start, InIter end, UnPred pfn);
The type ptrdiff_t is defined as some form of integer.
C h a p t e r 2 4 : I n t r o d u c i n g t h e S t a n d a r d T e m p l a t e L i b r a r y
665
Algorithm Purpose adjacent_find binary_search copy copy_backward count count_if equal equal_range
Searches for adjacent matching elements within a sequence and returns an iterator to the first match.
Performs a binary search on an ordered sequence.
Copies a sequence.
Same as copy( ) except that it moves the elements from the end of the sequence first.
Returns the number of elements in the sequence.
Returns the number of elements in the sequence that satisfy some predicate.
Determines if two ranges are the same.
Returns a range in which an element can be inserted into a sequence without disrupting the ordering of the sequence.
fill and fill_n find find_end find_first_of
Fills a range with the specified value.
Searches a range for a value and returns an iterator to the first occurrence of the element.
Searches a range for a subsequence. It returns an iterator to the end of the subsequence within the range.
Finds the first element within a sequence that matches an element within a range.
find_if Searches a range for an element for which a user-defined unary predicate returns true.
Applies a function to a range of elements.
for_each generate and generate_n Assign elements in a range the values returned by a generator function.
includes Determines if one sequence includes all of the elements in another sequence.
inplace_merge iter_swap
Merges a range with another range. Both ranges must be sorted in increasing order. The resulting sequence is sorted.
Exchanges the values pointed to by its two iterator arguments.
lexicographical_compare Alphabetically compares one sequence with another.
Table 24-5.
The STL Algorithms
666
C + + : T h e C o m p l e t e R e f e r e n c e
Algorithm lower_bound make_heap max max_element merge min min_element mismatch next_permutation nth_element partial_sort partial_sort_copy partition pop_heap prev_permutation push_heap random_shuffle remove, remove_if, remove_copy, and remove_copy_if replace, replace_copy, replace_if, and replace_copy_if
Purpose
Finds the first point in the sequence that is not less than a specified value.
Constructs a heap from a sequence.
Returns the maximum of two values.
Returns an iterator to the maximum element within a range.
Merges two ordered sequences, placing the result into a third sequence.
Returns the minimum of two values.
Returns an iterator to the minimum element within a range.
Finds first mismatch between the elements in two sequences. Iterators to the two elements are returned.
Constructs next permutation of a sequence.
Arranges a sequence such that all elements less than a specified element E come before that element and all elements greater than E come after it.
Sorts a range.
Sorts a range and then copies as many elements as will fit into a resulting sequence.
Arranges a sequence such that all elements for which a predicate returns true come before those for which the predicate returns false.
Exchanges the first and last
−1 elements and then rebuilds the heap.
Constructs previous permutation of a sequence.
Pushes an element onto the end of a heap.
Randomizes a sequence.
Removes elements from a specified range.
Replaces elements within a range.
Table 24-5.
The STL Algorithms ( continued
)
C h a p t e r 2 4 : I n t r o d u c i n g t h e S t a n d a r d T e m p l a t e L i b r a r y
667
Algorithm Purpose reverse and reverse_copy Reverses the order of a range.
rotate and rotate_copy Left-rotates the elements in a range.
search search_n
Searches for subsequence within a sequence.
Searches for a sequence of a specified number of similar elements.
set_difference set_intersection sort sort_heap stable_partition
Produces a sequence that contains the difference between two ordered sets.
Produces a sequence that contains the intersection of the two ordered sets.
set_symmetric_difference Produces a sequence that contains the symmetric difference between the two ordered sets.
set_union Produces a sequence that contains the union of the two ordered sets.
Sorts a range.
Sorts a heap within a specified range.
stable_sort
Arranges a sequence such that all elements for which a predicate returns true come before those for which the predicate returns false. The partitioning is stable. This means that the relative ordering of the sequence is preserved.
Sorts a range. The sort is stable. This means that equal elements are not rearranged.
swap swap_ranges transform
Exchanges two values.
Exchanges elements in a range.
Applies a function to a range of elements and stores the outcome in a new sequence.
unique and unique_copy Eliminates duplicate elements from a range.
upper_bound Finds the last point in a sequence that is not greater than some value.
Table 24-5.
The STL Algorithms ( continued )
668
C + + : T h e C o m p l e t e R e f e r e n c e
The count( ) algorithm returns the number of elements in the sequence beginning at
start and ending at end that match val. The count_if( ) algorithm returns the number of elements in the sequence beginning at start and ending at end for which the unary predicate pfn returns true.
The following program demonstrates count( ).
// Demonstrate count().
#include <iostream>
#include <vector>
#include <cstdlib>
#include <algorithm> using namespace std; int main()
{ vector<bool> v; unsigned int i; for(i=0; i < 10; i++) { if(rand() % 2) v.push_back(true);
} else v.push_back(false); cout << "Sequence:\n"; for(i=0; i<v.size(); i++) cout << boolalpha << v[i] << " "; cout << endl; i = count(v.begin(), v.end(), true); cout << i << " elements are true.\n";
} return 0;
This program displays the following output:
Sequence: true true false false true false false false false false
3 elements are true.
C h a p t e r 2 4 : I n t r o d u c i n g t h e S t a n d a r d T e m p l a t e L i b r a r y
669
The program begins by creating a vector comprised of randomly generated true and false values. Next, count( ) is used to count the number of true values.
This next program demonstrates count_if( ). It creates a vector containing the numbers 1 through 19. It then counts those that are evenly divisible by 3. To do this, it creates a unary predicate called dividesBy3( ), which returns true if its argument is evenly divisible by 3.
// Demonstrate count_if().
#include <iostream>
#include <vector>
#include <algorithm> using namespace std;
/* This is a unary predicate that determines if number is divisible by 3. */ bool dividesBy3(int i)
{ if((i%3) == 0) return true;
} return false; int main()
{ vector<int> v; int i; for(i=1; i < 20; i++) v.push_back(i); cout << "Sequence:\n"; for(i=0; i<v.size(); i++) cout << v[i] << " "; cout << endl; i = count_if(v.begin(), v.end(), dividesBy3); cout << i << " numbers are divisible by 3.\n";
} return 0;
This program produces the following output.
670
C + + : T h e C o m p l e t e R e f e r e n c e
Sequence:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
6 numbers are divisible by 3.
Notice how the unary predicate dividesBy3( ) is coded. All unary predicates receive as a parameter an object that is of the same type as that stored in the container upon which the predicate is operating. The predicate must then return a true or false result based upon this object.
Removing and Replacing Elements
Sometimes it is useful to generate a new sequence that consists of only certain items from an original sequence. One algorithm that does this is remove_copy( ). Its general form is shown here: template <class InIter, class OutIter, class T>
OutIter remove_copy(InIter start, InIter end,
OutIter result, const T &val);
The remove_copy( ) algorithm copies elements from the specified range, removing those that are equal to val. It puts the result into the sequence pointed to by result and returns an iterator to the end of the result. The output container must be large enough to hold the result.
To replace one element in a sequence with another when a copy is made, use
replace_copy( )
. Its general form is shown here: template <class InIter, class OutIter, class T>
OutIter replace_copy(InIter start, InIter end,
OutIter result, const T &old, const T &new);
The replace_copy( ) algorithm copies elements from the specified range, replacing elements equal to old with new. It puts the result into the sequence pointed to by result and returns an iterator to the end of the result. The output container must be large enough to hold the result.
The following program demonstrates remove_copy( ) and replace_copy( ). It creates a sequence of characters. It then removes all of the spaces from the sequence.
Next, it replaces all spaces with colons.
// Demonstrate remove_copy and replace_copy.
#include <iostream>
#include <vector>
#include <algorithm>
C h a p t e r 2 4 : I n t r o d u c i n g t h e S t a n d a r d T e m p l a t e L i b r a r y
671 using namespace std; int main()
{ char str[] = "The STL is power programming."; vector<char> v, v2(30); unsigned int i; for(i=0; str[i]; i++) v.push_back(str[i]);
// **** demonstrate remove_copy **** cout << "Input sequence:\n"; for(i=0; i<v.size(); i++) cout << v[i]; cout << endl;
// remove all spaces remove_copy(v.begin(), v.end(), v2.begin(), ' '); cout << "Result after removing spaces:\n"; for(i=0; i<v2.size(); i++) cout << v2[i]; cout << endl << endl;
// **** now, demonstrate replace_copy **** cout << "Input sequence:\n"; for(i=0; i<v.size(); i++) cout << v[i]; cout << endl;
// replace spaces with colons replace_copy(v.begin(), v.end(), v2.begin(), ' ', ':'); cout << "Result after replacing spaces with colons:\n"; for(i=0; i<v2.size(); i++) cout << v2[i]; cout << endl << endl;
} return 0;
The output produced by this program is shown here.
672
C + + : T h e C o m p l e t e R e f e r e n c e
Input sequence:
The STL is power programming.
Result after removing spaces:
TheSTLispowerprogramming.
Input sequence:
The STL is power programming.
Result after replacing spaces with colons:
The:STL:is:power:programming.
Reversing a Sequence
An often useful algorithm is reverse( ), which reverses a sequence. Its general form is template <class BiIter> void reverse(BiIter start, BiIter end);
The reverse( ) algorithm reverses the order of the range specified by start and end.
The following program demonstrates reverse( ).
// Demonstrate reverse.
#include <iostream>
#include <vector>
#include <algorithm> using namespace std; int main()
{ vector<int> v; unsigned int i; for(i=0; i<10; i++) v.push_back(i); cout << "Initial: "; for(i=0; i<v.size(); i++) cout << v[i] << " "; cout << endl; reverse(v.begin(), v.end()); cout << "Reversed: "; for(i=0; i<v.size(); i++) cout << v[i] << " ";
} return 0;
C h a p t e r 2 4 : I n t r o d u c i n g t h e S t a n d a r d T e m p l a t e L i b r a r y
673
The output from this program is shown here:
Initial: 0 1 2 3 4 5 6 7 8 9
Reversed: 9 8 7 6 5 4 3 2 1 0
Transforming a Sequence
One of the more interesting algorithms is transform( ) because it modifies each element in a range according to a function that you provide. The transform( ) algorithm has these two general forms: template <class InIter, class OutIter, class Func)
OutIter transform(InIter start, InIter end, OutIter result, Func unaryfunc); template <class InIter1, class InIter2, class OutIter, class Func)
OutIter transform(InIter1 start1, InIter1 end1, InIter2 start2,
OutIter result, Func binaryfunc);
The transform( ) algorithm applies a function to a range of elements and stores the outcome in result. In the first form, the range is specified by start and end. The function to be applied is specified unaryfunc. This function receives the value of an element in its parameter, and it must return its transformation. In the second form, the transformation is applied using a binary operator function that receives the value of an element from the sequence to be transformed in its first parameter and an element from the second sequence as its second parameter. Both versions return an iterator to the end of the resulting sequence.
The following program uses a simple transformation function called reciprocal( ) to transform the contents of a list of numbers into their reciprocals. Notice that the resulting sequence is stored in the same list that provided the original sequence.
// An example of the transform algorithm.
#include <iostream>
#include <list>
#include <algorithm> using namespace std;
// A simple transformation function.
double reciprocal(double i) { return 1.0/i; // return reciprocal
} int main()
674
C + + : T h e C o m p l e t e R e f e r e n c e
{ list<double> vals; int i;
// put values into list for(i=1; i<10; i++) vals.push_back((double)i); cout << "Original contents of vals:\n"; list<double>::iterator p = vals.begin(); while(p != vals.end()) { cout << *p << " "; p++;
} cout << endl;
// transform vals p = transform(vals.begin(), vals.end(), vals.begin(), reciprocal); cout << "Transformed contents of vals:\n"; p = vals.begin(); while(p != vals.end()) { cout << *p << " "; p++;
}
} return 0;
The output produced by the program is shown here:
Original contents of vals:
1 2 3 4 5 6 7 8 9
Transformed contents of vals:
1 0.5 0.333333 0.25 0.2 0.166667 0.142857 0.125 0.111111
As you can see, each element in vals has been transformed into its reciprocal.
Download
Advertisement
Key features
Covers the International Standard for C++
Includes advanced features such as overloading, inheritance, virtual functions, namespaces, templates, the STL, and RTTI
Works with all C++ compilers, including Visual C++
Written by world's leading programming author
More than 3 million copies sold worldwide
Frequently asked questions
This book covers a wide range of advanced features including overloading, inheritance, virtual functions, namespaces, templates, the STL, and RTTI.
This book works with all C++ compilers, including Visual C++.
This book is written by Herbert Schildt, the world's leading programming author.