Professional C__ - Marc Gregoire [235]
vector vector cout << inner_product(v1.cbegin(), v1.cend(), v2.cbegin(), 0) << endl; Code snippet from NonModifyingAlgorithms\inner_product.cpp The output is 70. Comparison Algorithms You can compare entire ranges of elements in three different ways: equal(), mismatch(), and lexicographical_compare(). These algorithms have the advantage that you can compare ranges in different containers. For example, you can compare the contents of a vector with the contents of a list. In general, these work best with sequential containers. They work by comparing the values in corresponding positions of the two collections to each other. equal() returns true if all corresponding elements are equal. It requires both containers to have the same number of elements. mismatch() returns iterators, one iterator for each of the collections, to indicate where in the range the corresponding elements mismatched. lexicographical_compare() deals with the situation where the two ranges may contain different numbers of elements. It returns true if all the elements in the first range are less than their corresponding elements in the second range, or, if the first range has fewer elements than the second and all elements in the first range are less than their corresponding initial subsequence in the second set. “lexicographical_compare” gets its name because it resembles the rules for comparing strings, but extends this set of rules to deal with objects of any type. If you want to compare the elements of two containers of the same type, you can use operator== or operator< instead of equal() or lexicographical_compare(). The algorithms are useful primarily for comparing sequences of elements from different container types. Here are some examples of these algorithms: // Function template to populate a container of ints. // The container must support push_back(). template void populateContainer(Container& cont) { int num; while (true) { cout << "Enter a number (0 to quit): "; cin >> num; if (num == 0) { break; } cont.push_back(num); } } int main() { vector list cout << "Populate the vector:" << endl; populateContainer(myVector); cout << "Populate the list:" << endl; populateContainer(myList); if (myList.size() < myVector.size()) { cout << "Sorry, the list is not long enough." << endl; return 1; } // compare the two containers if (equal(myVector.begin(), myVector.end(), myList.begin())) { cout << "The two containers have equal elements" << endl; } else { // If the containers were not equal, find out why not auto miss = mismatch(myVector.begin(), myVector.end(), myList.begin()); cout << "The following initial elements are " << "the same in the vector and the list:" << endl; for (auto i = myVector.begin(); i != miss.first; ++i) cout << *i << '\t'; cout << endl; } // Now order them. if (lexicographical_compare(myVector.begin(), myVector.end(), myList.begin(), myList.end())) { cout << "The vector is lexicographically first." << endl; } else { cout << "The list is lexicographically first." << endl; } return 0; } Code snippet from NonModifyingAlgorithms\ComparisonAlgorithms.cpp Here is a sample run of the program: Populate the vector: Enter a number (0 to quit): 5 Enter a number (0 to quit): 6 Enter a number (0 to quit): 7 Enter a number (0 to quit): 0 Populate the list: Enter a number (0 to quit): 5 Enter a number (0 to quit): 6 Enter a number (0 to quit): 9 Enter a number (0 to quit): 8 Enter a number (0 to quit): 0 The following initial elements are the same in the vector and the list: 5 6 The vector is lexicographically first. Operational Algorithms There is only one algorithm in this category: for_each(). However, it is one of the most useful algorithms in the STL. It executes a callback on each element of the range. You can use it with simple function callbacks or lambda expressions