Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
B.Eckel - Thinking in C++, Vol.2, 2nd edition.pdf
Скачиваний:
58
Добавлен:
08.05.2013
Размер:
2.09 Mб
Скачать

The find_end( ) test discovers the last occurrence of the entire sequence { 11, 11, 11 }. To show that it has in fact found the last occurrence, the rest of v starting from it is printed.

The first search_n( ) test looks for 3 copies of the value 7, which it finds and prints. When using the second version of search_n( ), the predicate is ordinarily meant to be used to determine equivalence between two elements, but I’ve taken some liberties and used a function object that multiplies the value in the sequence by (in this case) 15 and checks to see if it’s greater than 100. That is, the search_n( ) test above says “find me 6 consecutive values which, when multiplied by 15, each produce a number greater than 100.” Not exactly what you normally expect to do, but it might give you some ideas the next time you have an odd searching problem.

min_element( ) and max_element( ) are straightforward; the only thing that’s a bit odd is that it looks like the function is being dereferenced with a ‘*’. Actually, the returned iterator is being dereferenced to produce the value for printing.

To test replacements, replace_copy( ) is used first (so it doesn’t modify the original vector) to replace all values of 8 with the value 47. Notice the use of back_inserter( ) with the empty vector v2. To demonstrate replace_if( ), a function object is created using the standard template greater_equal along with bind2nd to replace all the values that are greater than or equal to 7 with the value -1.

Comparing ranges

These algorithms provide ways to compare two ranges. At first glance, the operations they perform seem very close to the search( ) function above. However, search( ) tells you where the second sequence appears within the first, while equal( ) and lexicographical_compare( ) simply tell you whether or not two sequences are exactly identical (using different comparison algorithms). On the other hand, mismatch( ) does tell you where the two sequences go out of sync, but those sequences must be exactly the same length.

bool equal(InputIterator first1, InputIterator last1, InputIterator first2); bool equal(InputIterator first1, InputIterator last1, InputIterator first2

BinaryPredicate binary_pred);

In both of these functions, the first range is the typical one, [first1, last1). The second range starts at first2, but there is no “last2” because its length is determined by the length of the first range. The equal( ) function returns true if both ranges are exactly the same (the same elements in the same order); in the first case, the operator== is used to perform the comparison and in the second case binary_pred is used to decide if two elements are the same.

bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1 InputIterator2 first2, InputIterator2 last2);

bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1 InputIterator2 first2, InputIterator2 last2, BinaryPredicate binary_pred);

Chapter 15: Multiple Inheritance

305

These two functions determine if the first range is “lexicographically less” than the second (they return true if range 1 is less than range 2, and false otherwise. Lexicographical equality, or “dictionary” comparison, means that the comparison is done the same way we establish the order of strings in a dictionary, one element at a time. The first elements determine the result if these elements are different, but if they’re equal the algorithm moves on to the next elements and looks at those, and so on. until it finds a mismatch. At that point it looks at the elements, and if the element from range 1 is less than the element from range two, then lexicographical_compare( ) returns true, otherwise it returns false. If it gets all the way through one range or the other (the ranges may be different lengths for this algorithm) without finding an inequality, then range 1 is not less than range 2 so the function returns false.

If the two ranges are different lengths, a missing element in one range acts as one that “precedes” an element that exists in the other range. So {‘a’, ‘b’} lexicographically precedes {‘a’, ‘b’, ‘a’ }.

In the first version of the function, operator< is used to perform the comparisons, and in the second version binary_pred is used.

pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2);

pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate binary_pred);

As in equal( ), the length of both ranges is exactly the same, so only the first iterator in the second range is necessary, and the length of the first range is used as the length of the second range. Whereas equal( ) just tells you whether or not the two ranges are the same, mismatch( ) tells you where they begin to differ. To accomplish this, you must be told (1) the element in the first range where the mismatch occurred and (2) the element in the second range where the mismatch occurred. These two iterators are packaged together into a pair object and returned. If no mismatch occurs, the return value is last1 combined with the past- the-end iterator of the second range.

As in equal( ), the first function tests for equality using operator== while the second one uses binary_pred.

Example

Because the standard C++ string class is built like a container (it has begin( ) and end( ) member functions which produce objects of type string::iterator), it can be used to conveniently create ranges of characters to test with the STL comparison algorithms. However, you should note that string has a fairly complete set of native operations, so you should look at the string class before using the STL algorithms to perform operations.

//: C05:Comparison.cpp

// The STL range comparison algorithms #include "PrintSequence.h"

#include <vector> #include <algorithm>

Chapter 15: Multiple Inheritance

306

#include <functional> #include <string> using namespace std;

int main() {

//strings provide a convenient way to create

//ranges of characters, but you should

//normally look for native string operations: string s1("This is a test");

string s2("This is a Test"); cout << "s1: " << s1 << endl

<<"s2: " << s2 << endl; cout << "compare s1 & s1: "

<<equal(s1.begin(), s1.end(), s1.begin())

<<endl;

cout << "compare s1 & s2: "

<<equal(s1.begin(), s1.end(), s2.begin())

<<endl;

cout << "lexicographical_compare s1 & s1: " << lexicographical_compare(s1.begin(), s1.end(),

s1.begin(), s1.end()) << endl;

cout << "lexicographical_compare s1 & s2: " << lexicographical_compare(s1.begin(), s1.end(),

s2.begin(), s2.end()) << endl;

cout << "lexicographical_compare s2 & s1: " << lexicographical_compare(s2.begin(), s2.end(),

s1.begin(), s1.end()) << endl;

cout << "lexicographical_compare shortened " "s1 & full-length s2: " << endl;

string s3(s1); while(s3.length() != 0) {

bool result = lexicographical_compare( s3.begin(), s3.end(), s2.begin(),s2.end());

cout << s3 << endl << s2 << ", result = " << result << endl;

if(result == true) break;

s3 = s3.substr(0, s3.length() - 1);

}

pair<string::iterator, string::iterator> p = mismatch(s1.begin(), s1.end(), s2.begin());

print(p.first, s1.end(), "p.first", ""); print(p.second, s2.end(), "p.second","");

} ///:~

Chapter 15: Multiple Inheritance

307

Соседние файлы в предмете Численные методы
  • #
    08.05.20133.99 Mб25A.Menezes, P.van Oorschot,S.Vanstone - HANDBOOK OF APPLIED CRYPTOGRAPHY.djvu
  • #
  • #
    08.05.20135.91 Mб28B.Eckel - Thinking in Java, 3rd edition (beta).pdf
  • #
  • #
    08.05.20136.09 Mб20D.MacKay - Information Theory, Inference, and Learning Algorithms.djvu
  • #
    08.05.20133.85 Mб19DIGITAL Visual Fortran ver.5.0 - Programmers Guide to Fortran.djvu
  • #
    08.05.20131.84 Mб16E.A.Lee, P.Varaiya - Structure and Interpretation of Signals and Systems.djvu