350 likes | 442 Views
CIS 4930 Application Development Using C++ Dr. Kun Suk Kim CISE Department, University of Florida. Non-Modifying Algorithm. Objectives. Counting Elements Minimum and Maximum Search Elements Comparing Ranges Sec 9.5. Counting Elements. template <class InputIterator,
E N D
CIS 4930Application Development Using C++Dr. Kun Suk KimCISE Department, University of Florida Non-Modifying Algorithm
Objectives • Counting Elements • Minimum and Maximum • Search Elements • Comparing Ranges • Sec 9.5
Counting Elements • template <class InputIterator, class EqualityComparable> iterator_traits<InputIterator>::difference_type count(InputIterator first, InputIterator last, const EqualityComparable& value); • Returns the number of iterators i in [first, last) such that *i == value
Counting Elements • template <class InputIterator, class Predicate> iterator_traits<InputIterator>::difference_type count_if(InputIterator first, InputIterator last, Predicate pred); • Returns the number of iterators i in [first, last) such that pred(*i) is true
Example – count1.cpp #include "algostuff.hpp“ using namespace std; bool isEven (int elem){ return elem % 2 == 0; } int main(){ vector<int> coll; int num; INSERT_ELEMENTS(coll,1,9); PRINT_ELEMENTS(coll,"coll: "); num = count (coll.begin(), coll.end(), 4); cout << "num of elements equal to 4: " << num << endl; num = count_if (coll.begin(), coll.end(), isEven); cout << "num of elements with even value: " << num << endl; num = count_if (coll.begin(), coll.end(), bind2nd(greater<int>(),4)); cout << "num of elements greater than 4: " << num << endl; return 0; } coll: 1 2 3 4 5 6 7 8 9 num of elements equal to 4: 1 num of elements with even value: 4 num of elements greater than 4: 5
Minimum and Maximum • template <class ForwardIterator> ForwardIterator min_element(ForwardIterator first, ForwardIterator last); • template <class ForwardIterator, class BinaryPredicate> ForwardIterator min_element(ForwardIterator first, ForwardIterator last, BinaryPredicate comp);
Minimum and Maximum • Min_element finds the smallest element in the range [first, last) • Returns the first iterator i in [first, last) such that no other iterator in [first, last) points to a value smaller than *i • Two versions • Differ in how they define whether one element is less than another • The first version compares objects using operator< • The second compares objects using a function object comp
Minimum and Maximum • template <class ForwardIterator> ForwardIterator max_element(ForwardIterator first, ForwardIterator last); • template <class ForwardIterator, class BinaryPredicate> ForwardIterator max_element(ForwardIterator first, ForwardIterator last, BinaryPredicate comp);
Minimum and Maximum • Max_element finds the largest element in the range [first, last) • Returns the first iterator i in [first, last) such that no other iterator in [first, last) points to a value greater than *i • Two versions • Differ in how they define whether one element is less than another • The first version compares objects using operator< • The second compares objects using a function object comp
Search First Matching Elements • template<class InputIterator, class EqualityComparable> InputIterator find(InputIterator first, InputIterator last, const EqualityComparable& value); • Returns the first iterator i in the range [first, last) such that *i == value • Returns last if no such iterator exists
Search First Matching Elements • template<class InputIterator, class Predicate> InputIterator find_if(InputIterator first, InputIterator last, Predicate pred); • Returns the first iterator i in the range [first, last) such that pred(*i) is true • Returns last if no such iterator exists
Example – find2.cpp #include "algostuff.hpp“ using namespace std; int main(){ vector<int> coll; vector<int>::iterator pos; INSERT_ELEMENTS(coll,1,9); PRINT_ELEMENTS(coll,"coll: "); pos = find_if (coll.begin(), coll.end(), bind2nd(greater<int>(),3)); cout << "the " << distance(coll.begin(),pos) + 1 << ". element is the first greater than 3" << endl; pos = find_if (coll.begin(), coll.end(), not1(bind2nd(modulus<int>(),3))); cout << "the " << distance(coll.begin(),pos) + 1 << ". element is the first divisible by 3" << endl; return 0; } coll: 1 2 3 4 5 6 7 8 9 the 4. element is the first greater than 3 the 3. element is the first divisible by 3
Search First n Matching Consecutive Elements • template <class ForwardIterator, class Integer, class T> ForwardIterator search_n(ForwardIterator first, ForwardIterator last, Integer count, const T& value); • template <class ForwardIterator, class Integer, class T, class BinaryPredicate> ForwardIterator search_n(ForwardIterator first, ForwardIterator last, Integer count, const T& value, BinaryPredicate binary_pred);
Search First n Matching Consecutive Elements • Search_n searches for a subsequence of count consecutive elements in the range [first, last), all of which are equal to value • Returns an iterator pointing to the beginning of that subsequence • Or else last if no such subsequence exists • Two versions • Differ in how they determine whether two elements are the same • The first uses operator== • The second uses the user-supplied function object binary_pred
Search First Subrange • template <class ForwardIterator1, class ForwardIterator2> ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); • template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate binary_pred);
Search First Subrange • Search finds a subsequence within the range [first1, last1) that is identical to [first2, last2) when compared element-by-element • Returns an iterator pointing to the beginning of that subsequence • Or else last1 if no such subsequence exists • Two versions • Differ in how they determine whether two elements are the same • The first uses operator== • The second uses the user-supplied function object binary_pred
Example – search2.cpp #include "algostuff.hpp“ using namespace std; bool checkEven (int elem, bool even) { if (even) return elem % 2 == 0; else return elem % 2 == 1; } int main(){ vector<int> coll; INSERT_ELEMENTS(coll,1,9); PRINT_ELEMENTS(coll,"coll: ");
Example – search2.cpp bool checkEvenArgs[3] = { true, false, true }; vector<int>::iterator pos; pos = search (coll.begin(), coll.end(), checkEvenArgs, checkEvenArgs+3, checkEven); while (pos != coll.end()) { cout << "subrange starting with element “ << distance(coll.begin(),pos) + 1<< endl; pos = search (++pos, coll.end(), checkEvenArgs, checkEvenArgs+3, checkEven); } return 0; } coll: 1 2 3 4 5 6 7 8 9 subrange starting with element 2 subrange starting with element 4 subrange starting with element 6
Search Last Subrange • template <class ForwardIterator1, class ForwardIterator2> ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); • template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate binary_pred);
Search Last Subrange • Find_end is misnamed • It is much more similar to search than to find, and a more accurate name would have been search_end • Find the last subsequence within the range [first1, last1) that is identical to [first2, last2)
Search Last Subrange • Returns an iterator pointing to the beginning of that subsequence • If no such subsequence exists, it returns last1 • Two versions • Differ in how they determine whether two elements are the same • The first uses operator== • The second uses the user-supplied function object comp
Search First of Several Possible Elements • template <class InputIterator, class ForwardIterator> InputIterator find_first_of(InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2); • template <class InputIterator, class ForwardIterator, class BinaryPredicate> InputIterator find_first_of(InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2, BinaryPredicate comp);
Search First of Several Possible Elements • Find_first_of is similar to find, in that it performs linear search through a range of Input Iterators • The difference is that while find searches for one particular value, find_first_of searches for any of several values • Find_first_of searches for the first occurrence in the range [first1, last1) of any of the elements in [first2, last2) • Two versions • Differ in how they compare elements for equality • The first uses operator== • The second uses the user-supplied function object comp
Search Two Adjacent, Equal Elements • template <class ForwardIterator> ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last); • template <class ForwardIterator, class BinaryPredicate> ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last, BinaryPredicate binary_pred);
Search Two Adjacent, Equal Elements • The first version: • Returns the first iterator i such that • i and i+1 are both valid iterators in [first, last) • *i == *(i+1) • Returns last if no such iterator exists • The second version: • Returns the first iterator i such that • i and i+1 are both valid iterators in [first, last) • binary_pred(*i, *(i+1)) is true • Returns last if no such iterator exists
Testing Equality • template <class InputIterator1, class InputIterator2> bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2); • template <class InputIterator1, class InputIterator2, class BinaryPredicate> bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate binary_pred);
Testing Equality • Equal returns true if the two ranges [first1, last1) and [first2, first2 + (last1 - first1)) are identical when compared element-by-element • Otherwise returns false • The caller must ensure that the range starting with first2 contains enough elements • binary_pred should not modify the passed arguments
Search the First Difference • template <class InputIterator1, class InputIterator2> pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2); • template <class InputIterator1, class InputIterator2, class BinaryPredicate> pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate binary_pred);
Search the First Difference • Mismatch finds the first position where the two ranges [first1, last1) and [first2, first2 + (last1 - first1)) differ • The first version of mismatch finds the first iterator i in [first1, last1) such that *i != *(first2 + (i - first1))
Search the First Difference • The return value is a pair whose first element is i and whose second element is *(first2 + (i - first1)) • If no such iterator i exists, the return value is a pair whose first element is last1 and whose second element is *(first2 + (last1 - first1)) • This does not mean that both sequences are equal, because the second sequence might contain more elements
Search the First Difference • The second version of mismatch finds the first iterator i in [first1, last1) such that binary_pred(*i, *(first2 + (i - first1)) is false • The caller must ensure that the range starting with first2 contains enough elements • binary_pred should not modify the passed arguments
Example – misma1.cpp #include "algostuff.hpp“ using namespace std; int main() { vector<int> coll1; list<int> coll2; INSERT_ELEMENTS(coll1,1,6); for (int i=1; i<=16; i*=2) coll2.push_back(i); coll2.push_back(3); PRINT_ELEMENTS(coll1,"coll1: "); PRINT_ELEMENTS(coll2,"coll2: "); pair<vector<int>::iterator,list<int>::iterator> values; values = mismatch (coll1.begin(), coll1.end(), coll2.begin()); if (values.first == coll1.end()) cout << "no mismatch" << endl; else cout << "first mismatch: " << *values.first << " and “ << *values.second << endl;
Example – misma1.cpp values = mismatch (coll1.begin(), coll1.end(), coll2.begin(), less_equal<int>()); if (values.first == coll1.end()) cout << "always less-or-equal" << endl; else cout << "not less-or-equal: " << *values.first << " and “ << *values.second << endl; } coll1: 1 2 3 4 5 6 coll2: 1 2 4 8 16 3 first mismatch: 3 and 4 not less-or-equal: 6 and 3
Testing for “Less Than” • template <class InputIterator1, class InputIterator2> bool lexcicographical_compare( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); • template <class InputIterator1, class InputIterator2, class BinaryPredicate> bool lexcicographical_compare( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate binary_pred);
Testing for “Less Than” • Lexicographical comparison • When two elements are not equal, the result of their comparison is the result of the whole comparison • When one sequence has no more elements to compare, then the sequence is less than the other • When both sequences have no more elements, then both sequences are equal, and the result of the comparison is false • binary_pred should not modify the passed arguments