Effective STL Terms 34

zhaozj2021-02-11  228

Terms 34: Note which algorithm requires an orderly interval

Not all algorithms can be used in any interval. For example, REMOVE (see Terms 32 and 33) requires forward iterators and the ability to assign values ​​through these iterator. Therefore, it cannot be applied to the intervals divided by the input iterator, nor can MAP or MULTIMAP, and cannot be some implementations of SET and MULTITISET (see Terms 22). Similarly, many sort algorithms (see Terms 31) need to random access iterators, so it is impossible to call these algorithms on an element element.

If you have made these rules, your code will not be able to compile, there may be a very lengthy and unacceptable error message (see Terms 49). But the needs of other algorithms are more embarrassed. Among these, the most common is that some algorithms require a sequential interval. You should adhere to this demand whenever, because it will not only lead to the diagnosis of the compiler, but will cause undefined period of time.

There are few algorithms that can be cooperated with ordered and unordered intervals, but they are most useful when operating an orderly interval. You can understand how these algorithms work, because it will explain why ordered intervals are best for them.

I know that some of you will use brute force, so there is a table that can only operate the algorithm of order data:

Binary_SearchLower_BoundUpper_boundequal_rangeset_unionset_intersectionSet_difference_symmetric_differencemergeinplace_mergeincludes

In addition, the following algorithms are generally used in an orderly interval, although they do not require:

Uniqueunique_copy

We will immediately see the definition of "order" is an important constraint, but first, let us be familiar with these algorithms. If you know why you need an orderly interval, it is easy to remember which algorithm needs that.

Search Algorithm Binary_Search, Lower_Bound, Upper_Bound and Equal_RANGE (see Terms 45) require an orderly interval because they use two binary looks to search for values. As BSearch in the C library, these algorithms guarantee the logging of log hours, but as an exchange, you must give them a value of the sequence.

In fact, these algorithms ensure that logarithm findings are not very correct. They only guarantee such performance when they pass them randomly access iterators. If you have a small iterator (such as two-way iterator), you still have a logarithmic comparison, but run is linear. It is because, the lack of the ability to "Aritithmetic". They need to spend linear time in the search interval to move from one place to another.

The four groups of algorithm set_union, set_intersection, set_difference, and set_symmetric_difference provide linear time to set the performance of their names. Why do they need an orderly interval? Because if not, they can't complete their work in linear time. If you start to find a trend - the algorithm that needs ordered intervals is to do so in order to provide better performance than them, you can do this, you are right. Keep coordination, this trend will continue.

MERGE and INPLACE_MERGE perform valid single-passing algorithm: they read two ordered intervals, then generate a new ordered interval containing all elements of two source intervals. They do linearly, if they don't know that the source intercom has been orderly, they cannot be completed.

The last algorithm that needs an orderly interval is incrudes. It is used to detect all objects in one interval are also in another interval. Because INCLUDES may assume that its two areas are already in order, it guarantees linear performance. There is no guarantee, generally it will slow down. Uniquely, unique and unique_copy, which we just discussed, even in disorder intervals. But look at how the standard describes the behavior of Unique (the oblique word is the mine area):

Remove all of the first elements from the continuous group of each equal element.

In other words, if you want unique to remove all repetition values ​​from a range (that is, let all the values ​​in the interval "unique"), you must first ensure that all repetition values ​​will follow one. Guess what? That is one of the things that are sorted. In fact, UNIQUE is generally used to remove all repetition values ​​from the interval, so you almost always make sure that you pass to Unique (or unique_copy) is ordered. (UNIX developers will find that STL's unique and UniQ's uniQ are amazing, I think this is never coincident.)

By the way, Unique is the same as the Element of an interval, which means that it is only distinguishable. If you don't know what it means, turn it immediately to Terms 32 and 33. Emphasizing that the importance of understanding the REMOVE and the REMOVE algorithm (including unique) is never excessive. It is not enough to have basic understandings. If you don't know what they do, you will fall into a dilemma.

This makes me to talk about the difficulty of the meaning of the meaning of the order. Because STL allows you to specify comparison functions for sorting, different intervals may be sorted in different ways. For example, give two int intervals, one may be sorted by default (as ascending), and the other uses Greater sort, therefore is descending. A given Widget two intervals, one may be sorted by price, and the other may be sorted by age. Because there are many different ways to sort, it is important to ensure that the sorting related information used by STL is important. If you pass a range to a comparison function, make sure that the comparison function behavior you passed and you are used to sort this range.

There is an example you don't want to do so here:

Vector v; // Create a vector,

... // put some data in

sort (v.begin (), v.end (), greater ()); // descending

... // Use this vector

// (Nothing to change it)

Bool a5exists = // Search 5 in this Vector 5

Binary_Search (v.begin (), v.end (), 5); // assumes that it is an ascending arrangement!

By default, Binary_Search assumes that its search is sorted in "<" (i.e., the value is ascending), but in this example, this vector is descending. When you call Binary_Search (or Lower_Bound, etc.) on different intervals desired by the algorithm, you should not be surprised when you have undefined results.

To make the code behavior correct, you have to tell binary_search to use and sort the same comparison function:

Bool a5exists = // Search 5

Binary_search (v.begin (), v.end (), 5. Greater ()); // Put the Greater as

// Compare function

All algorithms requiring an ordered interval (that is, all algorithms in the UNIQUE and UNIQUE_COPY Subject Terms) By the equivalent to determine whether the two values ​​"identical" are "the same", just like standard associated containers (which themselves are in an orderly). In contrast, unique and unique_copy determine that the default manner of the two objects "the same" is to pass equal, but you can overwrite this default by passing the meaning of the meaning of "the same" to these algorithms. Detailed discussion between equivalence and equality, reference clause 19.11 The algorithm that requires an orderly interval is doing this to provide better performance than other possibilities. As long as you remember to pass it to them, as long as you guarantee the comparison function for the algorithm and the consistency used to sort, you will love no trouble, set and merge, plus you will find unique and unique_copy Remove all repetition values, just as you want them to be completed.

转载请注明原文地址:https://www.9cbs.com/read-4773.html

New Post(0)