In the previous section, Basic String Usage, the last part of the
code in string2.cc
looked at counting the number of times the
letter 'a' occurred within the string sentence
. Intuitively, it
doesn't look too harmless; it's more than a few lines long, but such is
the price to pay for looking for the character we're interested
in. However, there is no need for this block of code; it's wasteful and
uses up far too much space. Why? Because there is a much easier way
to do this if you recall that there are a number of algorithms available
to us from the previous section; so why not use them? The algorithm of
interest is count
; the following example uses count
to do
exactly what the previous block of code did in string2.cc
:
cout << "Found " << count(sentence.begin(), sentence.end(), 'a') << " occurrences of 'a'" << endl;
count
is from <algorithm>
, of course, and seeing it at work here
makes it suddenly obvious how generic algorithms can be very potent things to
use. Remember however that we'd have to put #include <algorithm>
at the
start of the source file for it to be able to use count
. We're making
calls to begin
and end
to make use of the iterators provided by
string
. In one fell swoop, we've hacked down a larger piece of code
into a composite call to count
.
What kind of iterator are we using? In A Crash Course in Iterators,
there are a number of different kinds of iterator discussed, and each kind
gives us a clue as to how we can use them. string
uses a random access
iterator, in the same way that vector
and deque
use them. Like
the container classes that use random-access iterators, invalidation occurs
when the iterators are reallocated for some reason (such as deleting elements
etc.), so be careful how you use them.
Need to reverse a string? Use the reverse()
generic algorithm, given in
Generic Algorithm Summary. You can combine function objects with these
algorithms just like the examples in Function Adaptors - you are only
limited by the type of iterator that the algorithm takes as a parameter. Note
that although there are a number of searching algorithms available, the
string
class already provides for these (see String Summary).
The exciting thing about this is that we're making use of iterators and
generic algorithms to make code more readable and less dense. You'll find the
large collection of predefined string
operations more than enough in
most situations, so for the most part you might not need to look at generic
algorithms to do your work; we've mentioned it hear in passing so that you're
aware of the fact that since strings use iterators (begin()
and
end()
are already defined for you), we can use most generic algorithms
with the string
class.