📄 stl_algo.h
字号:
_EuclideanRingElement __t = __m % __n;
__m = __n;
__n = __t;
}
return __m;
}
/**
* @if maint
* This is a helper function for the rotate algorithm.
* @endif
*/
template<typename _ForwardIterator>
void
__rotate(_ForwardIterator __first,
_ForwardIterator __middle,
_ForwardIterator __last,
forward_iterator_tag)
{
if ((__first == __middle) || (__last == __middle))
return;
_ForwardIterator __first2 = __middle;
do
{
swap(*__first++, *__first2++);
if (__first == __middle)
__middle = __first2;
}
while (__first2 != __last);
__first2 = __middle;
while (__first2 != __last)
{
swap(*__first++, *__first2++);
if (__first == __middle)
__middle = __first2;
else if (__first2 == __last)
__first2 = __middle;
}
}
/**
* @if maint
* This is a helper function for the rotate algorithm.
* @endif
*/
template<typename _BidirectionalIterator>
void
__rotate(_BidirectionalIterator __first,
_BidirectionalIterator __middle,
_BidirectionalIterator __last,
bidirectional_iterator_tag)
{
// concept requirements
__glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<
_BidirectionalIterator>)
if ((__first == __middle) || (__last == __middle))
return;
std::__reverse(__first, __middle, bidirectional_iterator_tag());
std::__reverse(__middle, __last, bidirectional_iterator_tag());
while (__first != __middle && __middle != __last)
swap(*__first++, *--__last);
if (__first == __middle)
std::__reverse(__middle, __last, bidirectional_iterator_tag());
else
std::__reverse(__first, __middle, bidirectional_iterator_tag());
}
/**
* @if maint
* This is a helper function for the rotate algorithm.
* @endif
*/
template<typename _RandomAccessIterator>
void
__rotate(_RandomAccessIterator __first,
_RandomAccessIterator __middle,
_RandomAccessIterator __last,
random_access_iterator_tag)
{
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
if ((__first == __middle) || (__last == __middle))
return;
typedef typename iterator_traits<_RandomAccessIterator>::difference_type
_Distance;
typedef typename iterator_traits<_RandomAccessIterator>::value_type
_ValueType;
const _Distance __n = __last - __first;
const _Distance __k = __middle - __first;
const _Distance __l = __n - __k;
if (__k == __l)
{
std::swap_ranges(__first, __middle, __middle);
return;
}
const _Distance __d = __gcd(__n, __k);
for (_Distance __i = 0; __i < __d; __i++)
{
const _ValueType __tmp = *__first;
_RandomAccessIterator __p = __first;
if (__k < __l)
{
for (_Distance __j = 0; __j < __l / __d; __j++)
{
if (__p > __first + __l)
{
*__p = *(__p - __l);
__p -= __l;
}
*__p = *(__p + __k);
__p += __k;
}
}
else
{
for (_Distance __j = 0; __j < __k / __d - 1; __j ++)
{
if (__p < __last - __k)
{
*__p = *(__p + __k);
__p += __k;
}
*__p = * (__p - __l);
__p -= __l;
}
}
*__p = __tmp;
++__first;
}
}
/**
* @brief Rotate the elements of a sequence.
* @param first A forward iterator.
* @param middle A forward iterator.
* @param last A forward iterator.
* @return Nothing.
*
* Rotates the elements of the range @p [first,last) by @p (middle-first)
* positions so that the element at @p middle is moved to @p first, the
* element at @p middle+1 is moved to @first+1 and so on for each element
* in the range @p [first,last).
*
* This effectively swaps the ranges @p [first,middle) and
* @p [middle,last).
*
* Performs @p *(first+(n+(last-middle))%(last-first))=*(first+n) for
* each @p n in the range @p [0,last-first).
*/
template<typename _ForwardIterator>
inline void
rotate(_ForwardIterator __first, _ForwardIterator __middle,
_ForwardIterator __last)
{
// concept requirements
__glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
_ForwardIterator>)
__glibcxx_requires_valid_range(__first, __middle);
__glibcxx_requires_valid_range(__middle, __last);
typedef typename iterator_traits<_ForwardIterator>::iterator_category
_IterType;
std::__rotate(__first, __middle, __last, _IterType());
}
/**
* @brief Copy a sequence, rotating its elements.
* @param first A forward iterator.
* @param middle A forward iterator.
* @param last A forward iterator.
* @param result An output iterator.
* @return An iterator designating the end of the resulting sequence.
*
* Copies the elements of the range @p [first,last) to the range
* beginning at @result, rotating the copied elements by @p (middle-first)
* positions so that the element at @p middle is moved to @p result, the
* element at @p middle+1 is moved to @result+1 and so on for each element
* in the range @p [first,last).
*
* Performs @p *(result+(n+(last-middle))%(last-first))=*(first+n) for
* each @p n in the range @p [0,last-first).
*/
template<typename _ForwardIterator, typename _OutputIterator>
_OutputIterator
rotate_copy(_ForwardIterator __first, _ForwardIterator __middle,
_ForwardIterator __last, _OutputIterator __result)
{
// concept requirements
__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __middle);
__glibcxx_requires_valid_range(__middle, __last);
return std::copy(__first, __middle, copy(__middle, __last, __result));
}
/**
* @brief Randomly shuffle the elements of a sequence.
* @param first A forward iterator.
* @param last A forward iterator.
* @return Nothing.
*
* Reorder the elements in the range @p [first,last) using a random
* distribution, so that every possible ordering of the sequence is
* equally likely.
*/
template<typename _RandomAccessIterator>
inline void
random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_requires_valid_range(__first, __last);
if (__first != __last)
for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
std::iter_swap(__i, __first + (std::rand() % ((__i - __first) + 1)));
}
/**
* @brief Shuffle the elements of a sequence using a random number
* generator.
* @param first A forward iterator.
* @param last A forward iterator.
* @param rand The RNG functor or function.
* @return Nothing.
*
* Reorders the elements in the range @p [first,last) using @p rand to
* provide a random distribution. Calling @p rand(N) for a positive
* integer @p N should return a randomly chosen integer from the
* range [0,N).
*/
template<typename _RandomAccessIterator, typename _RandomNumberGenerator>
void
random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
_RandomNumberGenerator& __rand)
{
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_requires_valid_range(__first, __last);
if (__first == __last)
return;
for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
std::iter_swap(__i, __first + __rand((__i - __first) + 1));
}
/**
* @if maint
* This is a helper function...
* @endif
*/
template<typename _ForwardIterator, typename _Predicate>
_ForwardIterator
__partition(_ForwardIterator __first, _ForwardIterator __last,
_Predicate __pred,
forward_iterator_tag)
{
if (__first == __last)
return __first;
while (__pred(*__first))
if (++__first == __last)
return __first;
_ForwardIterator __next = __first;
while (++__next != __last)
if (__pred(*__next))
{
swap(*__first, *__next);
++__first;
}
return __first;
}
/**
* @if maint
* This is a helper function...
* @endif
*/
template<typename _BidirectionalIterator, typename _Predicate>
_BidirectionalIterator
__partition(_BidirectionalIterator __first, _BidirectionalIterator __last,
_Predicate __pred,
bidirectional_iterator_tag)
{
while (true)
{
while (true)
if (__first == __last)
return __first;
else if (__pred(*__first))
++__first;
else
break;
--__last;
while (true)
if (__first == __last)
return __first;
else if (!__pred(*__last))
--__last;
else
break;
std::iter_swap(__first, __last);
++__first;
}
}
/**
* @brief Move elements for which a predicate is true to the beginning
* of a sequence.
* @param first A forward iterator.
* @param last A forward iterator.
* @param pred A predicate functor.
* @return An iterator @p middle such that @p pred(i) is true for each
* iterator @p i in the range @p [first,middle) and false for each @p i
* in the range @p [middle,last).
*
* @p pred must not modify its operand. @p partition() does not preserve
* the relative ordering of elements in each group, use
* @p stable_partition() if this is needed.
*/
template<typename _ForwardIterator, typename _Predicate>
inline _ForwardIterator
partition(_ForwardIterator __first, _ForwardIterator __last,
_Predicate __pred)
{
// concept requirements
__glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
_ForwardIterator>)
__glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
return std::__partition(__first, __last, __pred,
std::__iterator_category(__first));
}
/**
* @if maint
* This is a helper function...
* @endif
*/
template<typename _ForwardIterator, typename _Predicate, typename _Distance>
_ForwardIterator
__inplace_stable_partition(_ForwardIterator __first,
_ForwardIterator __last,
_Predicate __pred, _Distance __len)
{
if (__len == 1)
return __pred(*__first) ? __last : __first;
_ForwardIterator __middle = __first;
std::advance(__middle, __len / 2);
_ForwardIterator __begin = std
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -