📄 stl_algo.h
字号:
return __last; _ForwardIterator __next = __first; while(++__next != __last) { if (__binary_pred(*__first, *__next)) return __first; __first = __next; } return __last; } /** * @brief Count the number of copies of a value in a sequence. * @param first An input iterator. * @param last An input iterator. * @param value The value to be counted. * @return The number of iterators @c i in the range @p [first,last) * for which @c *i == @p value */ template<typename _InputIterator, typename _Tp> typename iterator_traits<_InputIterator>::difference_type count(_InputIterator __first, _InputIterator __last, const _Tp& __value) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_InputIterator>::value_type, _Tp>) __glibcxx_requires_valid_range(__first, __last); typename iterator_traits<_InputIterator>::difference_type __n = 0; for ( ; __first != __last; ++__first) if (*__first == __value) ++__n; return __n; } /** * @brief Count the elements of a sequence for which a predicate is true. * @param first An input iterator. * @param last An input iterator. * @param pred A predicate. * @return The number of iterators @c i in the range @p [first,last) * for which @p pred(*i) is true. */ template<typename _InputIterator, typename _Predicate> typename iterator_traits<_InputIterator>::difference_type count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_InputIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); typename iterator_traits<_InputIterator>::difference_type __n = 0; for ( ; __first != __last; ++__first) if (__pred(*__first)) ++__n; return __n; } /** * @brief Search a sequence for a matching sub-sequence. * @param first1 A forward iterator. * @param last1 A forward iterator. * @param first2 A forward iterator. * @param last2 A forward iterator. * @return The first iterator @c i in the range * @p [first1,last1-(last2-first2)) such that @c *(i+N) == @p *(first2+N) * for each @c N in the range @p [0,last2-first2), or @p last1 if no * such iterator exists. * * Searches the range @p [first1,last1) for a sub-sequence that compares * equal value-by-value with the sequence given by @p [first2,last2) and * returns an iterator to the first element of the sub-sequence, or * @p last1 if the sub-sequence is not found. * * Because the sub-sequence must lie completely within the range * @p [first1,last1) it must start at a position less than * @p last1-(last2-first2) where @p last2-first2 is the length of the * sub-sequence. * This means that the returned iterator @c i will be in the range * @p [first1,last1-(last2-first2)) */ template<typename _ForwardIterator1, typename _ForwardIterator2> _ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_ForwardIterator1>::value_type, typename iterator_traits<_ForwardIterator2>::value_type>) __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); // Test for empty ranges if (__first1 == __last1 || __first2 == __last2) return __first1; // Test for a pattern of length 1. _ForwardIterator2 __tmp(__first2); ++__tmp; if (__tmp == __last2) return std::find(__first1, __last1, *__first2); // General case. _ForwardIterator2 __p1, __p; __p1 = __first2; ++__p1; _ForwardIterator1 __current = __first1; while (__first1 != __last1) { __first1 = std::find(__first1, __last1, *__first2); if (__first1 == __last1) return __last1; __p = __p1; __current = __first1; if (++__current == __last1) return __last1; while (*__current == *__p) { if (++__p == __last2) return __first1; if (++__current == __last1) return __last1; } ++__first1; } return __first1; } /** * @brief Search a sequence for a matching sub-sequence using a predicate. * @param first1 A forward iterator. * @param last1 A forward iterator. * @param first2 A forward iterator. * @param last2 A forward iterator. * @param predicate A binary predicate. * @return The first iterator @c i in the range * @p [first1,last1-(last2-first2)) such that * @p predicate(*(i+N),*(first2+N)) is true for each @c N in the range * @p [0,last2-first2), or @p last1 if no such iterator exists. * * Searches the range @p [first1,last1) for a sub-sequence that compares * equal value-by-value with the sequence given by @p [first2,last2), * using @p predicate to determine equality, and returns an iterator * to the first element of the sub-sequence, or @p last1 if no such * iterator exists. * * @see search(_ForwardIter1, _ForwardIter1, _ForwardIter2, _ForwardIter2) */ template<typename _ForwardIterator1, typename _ForwardIterator2, typename _BinaryPredicate> _ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __predicate) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, typename iterator_traits<_ForwardIterator1>::value_type, typename iterator_traits<_ForwardIterator2>::value_type>) __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); // Test for empty ranges if (__first1 == __last1 || __first2 == __last2) return __first1; // Test for a pattern of length 1. _ForwardIterator2 __tmp(__first2); ++__tmp; if (__tmp == __last2) { while (__first1 != __last1 && !__predicate(*__first1, *__first2)) ++__first1; return __first1; } // General case. _ForwardIterator2 __p1, __p; __p1 = __first2; ++__p1; _ForwardIterator1 __current = __first1; while (__first1 != __last1) { while (__first1 != __last1) { if (__predicate(*__first1, *__first2)) break; ++__first1; } while (__first1 != __last1 && !__predicate(*__first1, *__first2)) ++__first1; if (__first1 == __last1) return __last1; __p = __p1; __current = __first1; if (++__current == __last1) return __last1; while (__predicate(*__current, *__p)) { if (++__p == __last2) return __first1; if (++__current == __last1) return __last1; } ++__first1; } return __first1; } /** * @if maint * This is an uglified * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&) * overloaded for forward iterators. * @endif */ template<typename _ForwardIterator, typename _Integer, typename _Tp> _ForwardIterator __search_n(_ForwardIterator __first, _ForwardIterator __last, _Integer __count, const _Tp& __val, std::forward_iterator_tag) { __first = std::find(__first, __last, __val); while (__first != __last) { typename iterator_traits<_ForwardIterator>::difference_type __n = __count; _ForwardIterator __i = __first; ++__i; while (__i != __last && __n != 1 && *__i == __val) { ++__i; --__n; } if (__n == 1) return __first; if (__i == __last) return __last; __first = std::find(++__i, __last, __val); } return __last; } /** * @if maint * This is an uglified * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&) * overloaded for random access iterators. * @endif */ template<typename _RandomAccessIter, typename _Integer, typename _Tp> _RandomAccessIter __search_n(_RandomAccessIter __first, _RandomAccessIter __last, _Integer __count, const _Tp& __val, std::random_access_iterator_tag) { typedef typename std::iterator_traits<_RandomAccessIter>::difference_type _DistanceType; _DistanceType __tailSize = __last - __first; const _DistanceType __pattSize = __count; if (__tailSize < __pattSize) return __last; const _DistanceType __skipOffset = __pattSize - 1; _RandomAccessIter __lookAhead = __first + __skipOffset; __tailSize -= __pattSize; while (1) // the main loop... { // __lookAhead here is always pointing to the last element of next // possible match. while (!(*__lookAhead == __val)) // the skip loop... { if (__tailSize < __pattSize) return __last; // Failure __lookAhead += __pattSize; __tailSize -= __pattSize; } _DistanceType __remainder = __skipOffset; for (_RandomAccessIter __backTrack = __lookAhead - 1; *__backTrack == __val; --__backTrack) { if (--__remainder == 0) return (__lookAhead - __skipOffset); // Success } if (__remainder > __tailSize) return __last; // Failure __lookAhead += __remainder; __tailSize -= __remainder; } } /** * @brief Search a sequence for a number of consecutive values. * @param first A forward iterator. * @param last A forward iterator. * @param count The number of consecutive values. * @param val The value to find. * @return The first iterator @c i in the range @p [first,last-count) * such that @c *(i+N) == @p val for each @c N in the range @p [0,count), * or @p last if no such iterator exists. * * Searches the range @p [first,last) for @p count consecutive elements * equal to @p val. */ template<typename _ForwardIterator, typename _Integer, typename _Tp> _ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last, _Integer __count, const _Tp& __val) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_ForwardIterator>::value_type, _Tp>) __glibcxx_requires_valid_range(__first, __last); if (__count <= 0) return __first; if (__count == 1) return std::find(__first, __last, __val); return std::__search_n(__first, __last, __count, __val, std::__iterator_category(__first)); } /** * @if maint * This is an uglified * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&, * _BinaryPredicate) * overloaded for forward iterators. * @endif */ template<typename _ForwardIterator, typename _Integer, typename _Tp, typename _BinaryPredicate> _ForwardIterator __search_n(_ForwardIterator __first, _ForwardIterator __last, _Integer __count, const _Tp& __val, _BinaryPredicate __binary_pred, std::forward_iterator_tag) { while (__first != __last && !__binary_pred(*__first, __val)) ++__first; while (__first != __last) { typename iterator_traits<_ForwardIterator>::difference_type __n = __count; _ForwardIterator __i = __first; ++__i; while (__i != __last && __n != 1 && *__i == __val) { ++__i; --__n; } if (__n == 1) return __first; if (__i == __last) return __last; __first = ++__i; while (__first != __last && !__binary_pred(*__first, __val)) ++__first; } return __last; } /** * @if maint * This is an uglified * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&, * _BinaryPredicate) * overloaded for random access iterators. * @endif */ template<typename _RandomAccessIter, typename _Integer, typename _Tp, typename _BinaryPredicate> _RandomAccessIter __search_n(_RandomAccessIter __first, _RandomAccessIter __last, _Integer __count, const _Tp& __val, _BinaryPredicate __binary_pred, std::random_access_iterator_tag)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -