stl_algo.h
// Filename: <stl_algo.h> // Comment By: 凝霜
// E-mail: mdl2009@vip.qq.com
// Blog: http://blog.csdn.net/mdl13412 // 这个文件中定义了一些STL关键的算法, 我仅仅给出一个思路,
// 不进行详尽讲解, 具体算法请参考算法书籍, 推荐《算法导论》
// 另外, 对于基础薄弱的, 推荐《大话数据结构》, 此书我读了一下
// 试读章节, 适合初学者学习 /*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/ /* NOTE: This is an internal header file, included by other STL headers.
* You should not attempt to use it directly.
*/ #ifndef __SGI_STL_INTERNAL_ALGO_H
#define __SGI_STL_INTERNAL_ALGO_H #include <stl_heap.h> __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
#pragma set woff 1209
#endif // 选取a, b, c三个数中间的那个
template <class T>
inline const T& __median(const T& a, const T& b, const T& c) {
if (a < b)
if (b < c)
return b;
else if (a < c)
return c;
else
return a;
else if (a < c)
return a;
else if (b < c)
return c;
else
return b;
} template <class T, class Compare>
inline const T& __median(const T& a, const T& b, const T& c, Compare comp) {
if (comp(a, b))
if (comp(b, c))
return b;
else if (comp(a, c))
return c;
else
return a;
else if (comp(a, c))
return a;
else if (comp(b, c))
return c;
else
return b;
} // 对于[first, last)区间内的元素调用判别式
// 个人非常喜欢这个函数, 在C#中这个是语言层面就支持的
template <class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f) {
for ( ; first != last; ++first)
f(*first);
return f;
} // 查找指定区间内第一个值为value的元素
template <class InputIterator, class T>
InputIterator find(InputIterator first, InputIterator last, const T& value)
{
while (first != last && *first != value) ++first;
return first;
} // 查找指定区间内第一个满足判别式额元素
template <class InputIterator, class Predicate>
InputIterator find_if(InputIterator first, InputIterator last,
Predicate pred)
{
while (first != last && !pred(*first)) ++first;
return first;
} // 找出第一组满足条件的相邻元素
template <class ForwardIterator>
ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last)
{
if (first == last) return last;
ForwardIterator next = first;
while(++next != last) {
// 判断是否满足条件, 满足就返回
if (*first == *next) return first;
first = next;
}
return last;
} // 使用用户指定的二元比较判别式, 其余同上面
template <class ForwardIterator, class BinaryPredicate>
ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last,
BinaryPredicate binary_pred)
{
if (first == last) return last;
ForwardIterator next = first;
while(++next != last) {
if (binary_pred(*first, *next)) return first;
first = next;
}
return last;
} // 统计指定元素在指定区间内出现的次数
template <class InputIterator, class T, class Size>
void count(InputIterator first, InputIterator last, const T& value,
Size& n)
{
// 统计操作要历遍整个区间
for ( ; first != last; ++first)
if (*first == value)
++n;
} // 统计满足指定判别式的元素的个数
template <class InputIterator, class Predicate, class Size>
void count_if(InputIterator first, InputIterator last, Predicate pred,
Size& n) {
for ( ; first != last; ++first)
if (pred(*first))
++n;
} #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template <class InputIterator, class T>
typename iterator_traits<InputIterator>::difference_type
count(InputIterator first, InputIterator last, const T& value)
{
typename iterator_traits<InputIterator>::difference_type n = ;
for ( ; first != last; ++first)
if (*first == value)
++n;
return n;
} template <class InputIterator, class Predicate>
typename iterator_traits<InputIterator>::difference_type
count_if(InputIterator first, InputIterator last, Predicate pred) {
typename iterator_traits<InputIterator>::difference_type n = ;
for ( ; first != last; ++first)
if (pred(*first))
++n;
return n;
} #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template <class ForwardIterator1, class ForwardIterator2, class Distance1,
class Distance2>
ForwardIterator1 __search(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
Distance1*, Distance2*) {
Distance1 d1 = ;
distance(first1, last1, d1);
Distance2 d2 = ;
distance(first2, last2, d2); if (d1 < d2) return last1; ForwardIterator1 current1 = first1;
ForwardIterator2 current2 = first2; while (current2 != last2)
if (*current1 == *current2) {
++current1;
++current2;
}
else {
if (d1 == d2)
return last1;
else {
current1 = ++first1;
current2 = first2;
--d1;
}
}
return first1;
} // 在[first1, last1)区间内, 查找[first2, last2)区间
// 为了效率, 进行函数派发
template <class ForwardIterator1, class ForwardIterator2>
inline ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2)
{
return __search(first1, last1, first2, last2, distance_type(first1),
distance_type(first2));
} template <class ForwardIterator1, class ForwardIterator2,
class BinaryPredicate, class Distance1, class Distance2>
ForwardIterator1 __search(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
BinaryPredicate binary_pred, Distance1*, Distance2*) {
Distance1 d1 = ;
distance(first1, last1, d1);
Distance2 d2 = ;
distance(first2, last2, d2); if (d1 < d2) return last1; ForwardIterator1 current1 = first1;
ForwardIterator2 current2 = first2; while (current2 != last2)
if (binary_pred(*current1, *current2)) {
++current1;
++current2;
}
else {
if (d1 == d2)
return last1;
else {
current1 = ++first1;
current2 = first2;
--d1;
}
}
return first1;
} template <class ForwardIterator1, class ForwardIterator2,
class BinaryPredicate>
inline ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
BinaryPredicate binary_pred) {
return __search(first1, last1, first2, last2, binary_pred,
distance_type(first1), distance_type(first2));
} // 在[first, last)内查找第一个满足连续count个value的位置
template <class ForwardIterator, class Integer, class T>
ForwardIterator search_n(ForwardIterator first, ForwardIterator last,
Integer count, const T& value)
{
if (count <= )
return first;
else {
first = find(first, last, value);
while (first != last) {
Integer n = count - ;
ForwardIterator i = first;
++i;
while (i != last && n != && *i == value) {
++i;
--n;
}
if (n == )
return first;
else
first = find(i, last, value);
}
return last;
}
} // 好吧, 二元判别式自己指定的
template <class ForwardIterator, class Integer, class T, class BinaryPredicate>
ForwardIterator search_n(ForwardIterator first, ForwardIterator last,
Integer count, const T& value,
BinaryPredicate binary_pred) {
if (count <= )
return first;
else {
while (first != last) {
if (binary_pred(*first, value)) break;
++first;
}
while (first != last) {
Integer n = count - ;
ForwardIterator i = first;
++i;
while (i != last && n != && binary_pred(*i, value)) {
++i;
--n;
}
if (n == )
return first;
else {
while (i != last) {
if (binary_pred(*i, value)) break;
++i;
}
first = i;
}
}
return last;
}
} // 交换两个区间内的元素, 要求长度相同
template <class ForwardIterator1, class ForwardIterator2>
ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2)
{
for ( ; first1 != last1; ++first1, ++first2)
iter_swap(first1, first2);
return first2;
} // 将[first, last)经判别式转换到result处
template <class InputIterator, class OutputIterator, class UnaryOperation>
OutputIterator transform(InputIterator first, InputIterator last,
OutputIterator result, UnaryOperation op)
{
for ( ; first != last; ++first, ++result)
*result = op(*first);
return result;
} // 这个多了一个区间
template <class InputIterator1, class InputIterator2, class OutputIterator,
class BinaryOperation>
OutputIterator transform(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, OutputIterator result,
BinaryOperation binary_op)
{
for ( ; first1 != last1; ++first1, ++first2, ++result)
*result = binary_op(*first1, *first2);
return result;
} // 将[first, last)内的old_value都以new_value替代
template <class ForwardIterator, class T>
void replace(ForwardIterator first, ForwardIterator last, const T& old_value,
const T& new_value)
{
for ( ; first != last; ++first)
if (*first == old_value) *first = new_value;
} // 将[first, last)内的满足判别式的元素都以new_value代替
template <class ForwardIterator, class Predicate, class T>
void replace_if(ForwardIterator first, ForwardIterator last, Predicate pred,
const T& new_value)
{
for ( ; first != last; ++first)
if (pred(*first)) *first = new_value;
} // 与replace唯一不同的是会将元素复制到新的位置
template <class InputIterator, class OutputIterator, class T>
OutputIterator replace_copy(InputIterator first, InputIterator last,
OutputIterator result, const T& old_value,
const T& new_value)
{
for ( ; first != last; ++first, ++result)
*result = *first == old_value ? new_value : *first;
return result;
} // 同上
template <class Iterator, class OutputIterator, class Predicate, class T>
OutputIterator replace_copy_if(Iterator first, Iterator last,
OutputIterator result, Predicate pred,
const T& new_value)
{
for ( ; first != last; ++first, ++result)
*result = pred(*first) ? new_value : *first;
return result;
} // 将仿函数的处理结果填充在[first, last)区间内
// 对于用户自定义类型要提供operator =()
template <class ForwardIterator, class Generator>
void generate(ForwardIterator first, ForwardIterator last, Generator gen)
{
for ( ; first != last; ++first)
*first = gen();
} // 和generate()差不多, 只是给定的是起点和个数
template <class OutputIterator, class Size, class Generator>
OutputIterator generate_n(OutputIterator first, Size n, Generator gen)
{
for ( ; n > ; --n, ++first)
*first = gen();
return first;
} // 将[first, last)中除了value的元素拷贝到result处
// 注意: 这里使用的是operator =(), 用户自定义类型要注意资源的析构
template <class InputIterator, class OutputIterator, class T>
OutputIterator remove_copy(InputIterator first, InputIterator last,
OutputIterator result, const T& value)
{
for ( ; first != last; ++first)
if (*first != value) {
*result = *first;
++result;
}
return result;
} // 将[first, last)中除了满足判别式的元素拷贝到result处
// 注意: 这里使用的是operator =(), 用户自定义类型要注意资源的析构
template <class InputIterator, class OutputIterator, class Predicate>
OutputIterator remove_copy_if(InputIterator first, InputIterator last,
OutputIterator result, Predicate pred)
{
for ( ; first != last; ++first)
if (!pred(*first)) {
*result = *first;
++result;
}
return result;
} // 移除指定值的元素, 但是并不删除
template <class ForwardIterator, class T>
ForwardIterator remove(ForwardIterator first, ForwardIterator last,
const T& value)
{
first = find(first, last, value);
ForwardIterator next = first;
return first == last ? first : remove_copy(++next, last, first, value);
} // 移除满足判别式的元素, 但是并不删除
template <class ForwardIterator, class Predicate>
ForwardIterator remove_if(ForwardIterator first, ForwardIterator last,
Predicate pred)
{
first = find_if(first, last, pred);
ForwardIterator next = first;
return first == last ? first : remove_copy_if(++next, last, first, pred);
} template <class InputIterator, class ForwardIterator>
ForwardIterator __unique_copy(InputIterator first, InputIterator last,
ForwardIterator result, forward_iterator_tag) {
*result = *first;
while (++first != last)
if (*result != *first) *++result = *first;
return ++result;
} template <class InputIterator, class OutputIterator, class T>
OutputIterator __unique_copy(InputIterator first, InputIterator last,
OutputIterator result, T*) {
T value = *first;
*result = value;
while (++first != last)
if (value != *first) {
value = *first;
*++result = value;
}
return ++result;
} template <class InputIterator, class OutputIterator>
inline OutputIterator __unique_copy(InputIterator first, InputIterator last,
OutputIterator result,
output_iterator_tag) {
return __unique_copy(first, last, result, value_type(first));
} template <class InputIterator, class OutputIterator>
inline OutputIterator unique_copy(InputIterator first, InputIterator last,
OutputIterator result) {
if (first == last) return result;
return __unique_copy(first, last, result, iterator_category(result));
}
template <class InputIterator, class ForwardIterator, class BinaryPredicate>
ForwardIterator __unique_copy(InputIterator first, InputIterator last,
ForwardIterator result,
BinaryPredicate binary_pred,
forward_iterator_tag) {
*result = *first;
while (++first != last)
if (!binary_pred(*result, *first)) *++result = *first;
return ++result;
} template <class InputIterator, class OutputIterator, class BinaryPredicate,
class T>
OutputIterator __unique_copy(InputIterator first, InputIterator last,
OutputIterator result,
BinaryPredicate binary_pred, T*) {
T value = *first;
*result = value;
while (++first != last)
if (!binary_pred(value, *first)) {
value = *first;
*++result = value;
}
return ++result;
} template <class InputIterator, class OutputIterator, class BinaryPredicate>
inline OutputIterator __unique_copy(InputIterator first, InputIterator last,
OutputIterator result,
BinaryPredicate binary_pred,
output_iterator_tag) {
return __unique_copy(first, last, result, binary_pred, value_type(first));
} template <class InputIterator, class OutputIterator, class BinaryPredicate>
inline OutputIterator unique_copy(InputIterator first, InputIterator last,
OutputIterator result,
BinaryPredicate binary_pred) {
if (first == last) return result;
return __unique_copy(first, last, result, binary_pred,
iterator_category(result));
} // 删除所有相邻重复元素
template <class ForwardIterator>
ForwardIterator unique(ForwardIterator first, ForwardIterator last)
{
first = adjacent_find(first, last);
return unique_copy(first, last, first);
} // 好吧, 删除所有相邻重复元素, 并拷贝到指定位置
template <class ForwardIterator, class BinaryPredicate>
ForwardIterator unique(ForwardIterator first, ForwardIterator last,
BinaryPredicate binary_pred)
{
first = adjacent_find(first, last, binary_pred);
return unique_copy(first, last, first, binary_pred);
} template <class BidirectionalIterator>
void __reverse(BidirectionalIterator first, BidirectionalIterator last,
bidirectional_iterator_tag)
{
while (true)
if (first == last || first == --last)
return;
else
iter_swap(first++, last);
} template <class RandomAccessIterator>
void __reverse(RandomAccessIterator first, RandomAccessIterator last,
random_access_iterator_tag)
{
while (first < last) iter_swap(first++, --last);
} // 将[first, last)内的元素倒置
// 还是为了效率进行函数派发, 不做解释了
template <class BidirectionalIterator>
inline void reverse(BidirectionalIterator first, BidirectionalIterator last)
{
__reverse(first, last, iterator_category(first));
} // 好吧, 和reverse的区别是会把处理后的元素拷贝到新区间
template <class BidirectionalIterator, class OutputIterator>
OutputIterator reverse_copy(BidirectionalIterator first,
BidirectionalIterator last,
OutputIterator result)
{
while (first != last) {
--last;
*result = *last;
++result;
}
return result;
} template <class ForwardIterator, class Distance>
void __rotate(ForwardIterator first, ForwardIterator middle,
ForwardIterator last, Distance*, forward_iterator_tag) {
for (ForwardIterator i = middle; ;) {
iter_swap(first, i);
++first;
++i;
if (first == middle) {
if (i == last) return;
middle = i;
}
else if (i == last)
i = middle;
}
} template <class BidirectionalIterator, class Distance>
void __rotate(BidirectionalIterator first, BidirectionalIterator middle,
BidirectionalIterator last, Distance*,
bidirectional_iterator_tag) {
reverse(first, middle);
reverse(middle, last);
reverse(first, last);
} // 这个你要是都不知道那就马上去学习数据结构的知识吧
template <class EuclideanRingElement>
EuclideanRingElement __gcd(EuclideanRingElement m, EuclideanRingElement n)
{
while (n != ) {
EuclideanRingElement t = m % n;
m = n;
n = t;
}
return m;
} template <class RandomAccessIterator, class Distance, class T>
void __rotate_cycle(RandomAccessIterator first, RandomAccessIterator last,
RandomAccessIterator initial, Distance shift, T*) {
T value = *initial;
RandomAccessIterator ptr1 = initial;
RandomAccessIterator ptr2 = ptr1 + shift;
while (ptr2 != initial) {
*ptr1 = *ptr2;
ptr1 = ptr2;
if (last - ptr2 > shift)
ptr2 += shift;
else
ptr2 = first + (shift - (last - ptr2));
}
*ptr1 = value;
} template <class RandomAccessIterator, class Distance>
void __rotate(RandomAccessIterator first, RandomAccessIterator middle,
RandomAccessIterator last, Distance*,
random_access_iterator_tag) {
Distance n = __gcd(last - first, middle - first);
while (n--)
__rotate_cycle(first, last, first + n, middle - first,
value_type(first));
} // 将[first, middle)和[middle, last)内元素互换
// 还是为了效率, 进行函数派发, 不解释了
template <class ForwardIterator>
inline void rotate(ForwardIterator first, ForwardIterator middle,
ForwardIterator last) {
if (first == middle || middle == last) return;
__rotate(first, middle, last, distance_type(first),
iterator_category(first));
} // 和rotate唯一的区别就是将旋转后的元素拷贝到新位置
template <class ForwardIterator, class OutputIterator>
OutputIterator rotate_copy(ForwardIterator first, ForwardIterator middle,
ForwardIterator last, OutputIterator result) {
return copy(first, middle, copy(middle, last, result));
} template <class RandomAccessIterator, class Distance>
void __random_shuffle(RandomAccessIterator first, RandomAccessIterator last,
Distance*) {
if (first == last) return;
for (RandomAccessIterator i = first + ; i != last; ++i)
#ifdef __STL_NO_DRAND48
iter_swap(i, first + Distance(rand() % ((i - first) + )));
#else
iter_swap(i, first + Distance(lrand48() % ((i - first) + )));
#endif
} template <class RandomAccessIterator>
inline void random_shuffle(RandomAccessIterator first,
RandomAccessIterator last) {
__random_shuffle(first, last, distance_type(first));
} // 产生随机的排列
template <class RandomAccessIterator, class RandomNumberGenerator>
void random_shuffle(RandomAccessIterator first, RandomAccessIterator last,
RandomNumberGenerator& rand)
{
if (first == last) return;
for (RandomAccessIterator i = first + ; i != last; ++i)
iter_swap(i, first + rand((i - first) + ));
} template <class ForwardIterator, class OutputIterator, class Distance>
OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last,
OutputIterator out, const Distance n)
{
Distance remaining = ;
distance(first, last, remaining);
Distance m = min(n, remaining); while (m > ) {
#ifdef __STL_NO_DRAND48
if (rand() % remaining < m) {
#else
if (lrand48() % remaining < m) {
#endif
*out = *first;
++out;
--m;
} --remaining;
++first;
}
return out;
} template <class ForwardIterator, class OutputIterator, class Distance,
class RandomNumberGenerator>
OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last,
OutputIterator out, const Distance n,
RandomNumberGenerator& rand)
{
Distance remaining = ;
distance(first, last, remaining);
Distance m = min(n, remaining); while (m > ) {
if (rand(remaining) < m) {
*out = *first;
++out;
--m;
} --remaining;
++first;
}
return out;
} template <class InputIterator, class RandomAccessIterator, class Distance>
RandomAccessIterator __random_sample(InputIterator first, InputIterator last,
RandomAccessIterator out,
const Distance n)
{
Distance m = ;
Distance t = n;
for ( ; first != last && m < n; ++m, ++first)
out[m] = *first; while (first != last) {
++t;
#ifdef __STL_NO_DRAND48
Distance M = rand() % t;
#else
Distance M = lrand48() % t;
#endif
if (M < n)
out[M] = *first;
++first;
} return out + m;
} template <class InputIterator, class RandomAccessIterator,
class RandomNumberGenerator, class Distance>
RandomAccessIterator __random_sample(InputIterator first, InputIterator last,
RandomAccessIterator out,
RandomNumberGenerator& rand,
const Distance n)
{
Distance m = ;
Distance t = n;
for ( ; first != last && m < n; ++m, ++first)
out[m] = *first; while (first != last) {
++t;
Distance M = rand(t);
if (M < n)
out[M] = *first;
++first;
} return out + m;
} template <class InputIterator, class RandomAccessIterator>
inline RandomAccessIterator
random_sample(InputIterator first, InputIterator last,
RandomAccessIterator out_first, RandomAccessIterator out_last)
{
return __random_sample(first, last, out_first, out_last - out_first);
} template <class InputIterator, class RandomAccessIterator,
class RandomNumberGenerator>
inline RandomAccessIterator
random_sample(InputIterator first, InputIterator last,
RandomAccessIterator out_first, RandomAccessIterator out_last,
RandomNumberGenerator& rand)
{
return __random_sample(first, last, out_first, rand, out_last - out_first);
} // 将[first, last)区间内元素重新排序, 所有满足判别式的元素都被放在前面
template <class BidirectionalIterator, class Predicate>
BidirectionalIterator partition(BidirectionalIterator first,
BidirectionalIterator last, Predicate pred)
{
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;
iter_swap(first, last);
++first;
}
} template <class ForwardIterator, class Predicate, class Distance>
ForwardIterator __inplace_stable_partition(ForwardIterator first,
ForwardIterator last,
Predicate pred, Distance len) {
if (len == ) return pred(*first) ? last : first;
ForwardIterator middle = first;
advance(middle, len / );
ForwardIterator
first_cut = __inplace_stable_partition(first, middle, pred, len / );
ForwardIterator
second_cut = __inplace_stable_partition(middle, last, pred,
len - len / );
rotate(first_cut, middle, second_cut);
len = ;
distance(middle, second_cut, len);
advance(first_cut, len);
return first_cut;
} template <class ForwardIterator, class Pointer, class Predicate,
class Distance>
ForwardIterator __stable_partition_adaptive(ForwardIterator first,
ForwardIterator last,
Predicate pred, Distance len,
Pointer buffer,
Distance buffer_size) {
if (len <= buffer_size) {
ForwardIterator result1 = first;
Pointer result2 = buffer;
for ( ; first != last ; ++first)
if (pred(*first)) {
*result1 = *first;
++result1;
}
else {
*result2 = *first;
++result2;
}
copy(buffer, result2, result1);
return result1;
}
else {
ForwardIterator middle = first;
advance(middle, len / );
ForwardIterator first_cut =
__stable_partition_adaptive(first, middle, pred, len / ,
buffer, buffer_size);
ForwardIterator second_cut =
__stable_partition_adaptive(middle, last, pred, len - len / ,
buffer, buffer_size); rotate(first_cut, middle, second_cut);
len = ;
distance(middle, second_cut, len);
advance(first_cut, len);
return first_cut;
}
} template <class ForwardIterator, class Predicate, class T, class Distance>
inline ForwardIterator __stable_partition_aux(ForwardIterator first,
ForwardIterator last,
Predicate pred, T*, Distance*) {
temporary_buffer<ForwardIterator, T> buf(first, last);
if (buf.size() > )
return __stable_partition_adaptive(first, last, pred,
Distance(buf.requested_size()),
buf.begin(), buf.size());
else
return __inplace_stable_partition(first, last, pred,
Distance(buf.requested_size()));
} template <class ForwardIterator, class Predicate>
inline ForwardIterator stable_partition(ForwardIterator first,
ForwardIterator last,
Predicate pred) {
if (first == last)
return first;
else
return __stable_partition_aux(first, last, pred,
value_type(first), distance_type(first));
} template <class RandomAccessIterator, class T>
RandomAccessIterator __unguarded_partition(RandomAccessIterator first,
RandomAccessIterator last,
T pivot) {
while (true) {
while (*first < pivot) ++first;
--last;
while (pivot < *last) --last;
if (!(first < last)) return first;
iter_swap(first, last);
++first;
}
} template <class RandomAccessIterator, class T, class Compare>
RandomAccessIterator __unguarded_partition(RandomAccessIterator first,
RandomAccessIterator last,
T pivot, Compare comp) {
while () {
while (comp(*first, pivot)) ++first;
--last;
while (comp(pivot, *last)) --last;
if (!(first < last)) return first;
iter_swap(first, last);
++first;
}
} const int __stl_threshold = ; template <class RandomAccessIterator, class T>
void __unguarded_linear_insert(RandomAccessIterator last, T value) {
RandomAccessIterator next = last;
--next;
while (value < *next) {
*last = *next;
last = next;
--next;
}
*last = value;
} template <class RandomAccessIterator, class T, class Compare>
void __unguarded_linear_insert(RandomAccessIterator last, T value,
Compare comp) {
RandomAccessIterator next = last;
--next;
while (comp(value , *next)) {
*last = *next;
last = next;
--next;
}
*last = value;
} template <class RandomAccessIterator, class T>
inline void __linear_insert(RandomAccessIterator first,
RandomAccessIterator last, T*) {
T value = *last;
if (value < *first) {
copy_backward(first, last, last + );
*first = value;
}
else
__unguarded_linear_insert(last, value);
} template <class RandomAccessIterator, class T, class Compare>
inline void __linear_insert(RandomAccessIterator first,
RandomAccessIterator last, T*, Compare comp) {
T value = *last;
if (comp(value, *first)) {
copy_backward(first, last, last + );
*first = value;
}
else
__unguarded_linear_insert(last, value, comp);
} template <class RandomAccessIterator>
void __insertion_sort(RandomAccessIterator first, RandomAccessIterator last) {
if (first == last) return;
for (RandomAccessIterator i = first + ; i != last; ++i)
__linear_insert(first, i, value_type(first));
} template <class RandomAccessIterator, class Compare>
void __insertion_sort(RandomAccessIterator first,
RandomAccessIterator last, Compare comp) {
if (first == last) return;
for (RandomAccessIterator i = first + ; i != last; ++i)
__linear_insert(first, i, value_type(first), comp);
} template <class RandomAccessIterator, class T>
void __unguarded_insertion_sort_aux(RandomAccessIterator first,
RandomAccessIterator last, T*) {
for (RandomAccessIterator i = first; i != last; ++i)
__unguarded_linear_insert(i, T(*i));
} template <class RandomAccessIterator>
inline void __unguarded_insertion_sort(RandomAccessIterator first,
RandomAccessIterator last) {
__unguarded_insertion_sort_aux(first, last, value_type(first));
} template <class RandomAccessIterator, class T, class Compare>
void __unguarded_insertion_sort_aux(RandomAccessIterator first,
RandomAccessIterator last,
T*, Compare comp) {
for (RandomAccessIterator i = first; i != last; ++i)
__unguarded_linear_insert(i, T(*i), comp);
} template <class RandomAccessIterator, class Compare>
inline void __unguarded_insertion_sort(RandomAccessIterator first,
RandomAccessIterator last,
Compare comp) {
__unguarded_insertion_sort_aux(first, last, value_type(first), comp);
} template <class RandomAccessIterator>
void __final_insertion_sort(RandomAccessIterator first,
RandomAccessIterator last) {
if (last - first > __stl_threshold) {
__insertion_sort(first, first + __stl_threshold);
__unguarded_insertion_sort(first + __stl_threshold, last);
}
else
__insertion_sort(first, last);
} template <class RandomAccessIterator, class Compare>
void __final_insertion_sort(RandomAccessIterator first,
RandomAccessIterator last, Compare comp) {
if (last - first > __stl_threshold) {
__insertion_sort(first, first + __stl_threshold, comp);
__unguarded_insertion_sort(first + __stl_threshold, last, comp);
}
else
__insertion_sort(first, last, comp);
} template <class Size>
inline Size __lg(Size n) {
Size k;
for (k = ; n > ; n >>= ) ++k;
return k;
} template <class RandomAccessIterator, class T, class Size>
void __introsort_loop(RandomAccessIterator first,
RandomAccessIterator last, T*,
Size depth_limit) {
while (last - first > __stl_threshold) {
if (depth_limit == ) {
partial_sort(first, last, last);
return;
}
--depth_limit;
RandomAccessIterator cut = __unguarded_partition
(first, last, T(__median(*first, *(first + (last - first)/),
*(last - ))));
__introsort_loop(cut, last, value_type(first), depth_limit);
last = cut;
}
} template <class RandomAccessIterator, class T, class Size, class Compare>
void __introsort_loop(RandomAccessIterator first,
RandomAccessIterator last, T*,
Size depth_limit, Compare comp) {
while (last - first > __stl_threshold) {
if (depth_limit == ) {
partial_sort(first, last, last, comp);
return;
}
--depth_limit;
RandomAccessIterator cut = __unguarded_partition
(first, last, T(__median(*first, *(first + (last - first)/),
*(last - ), comp)), comp);
__introsort_loop(cut, last, value_type(first), depth_limit, comp);
last = cut;
}
} // 必须为随RandomAccessIterator, 排序算法要根据情况进行派发
template <class RandomAccessIterator>
inline void sort(RandomAccessIterator first, RandomAccessIterator last)
{
if (first != last) {
__introsort_loop(first, last, value_type(first), __lg(last - first) * );
__final_insertion_sort(first, last);
}
} template <class RandomAccessIterator, class Compare>
inline void sort(RandomAccessIterator first, RandomAccessIterator last,
Compare comp) {
if (first != last) {
__introsort_loop(first, last, value_type(first), __lg(last - first) * ,
comp);
__final_insertion_sort(first, last, comp);
}
} template <class RandomAccessIterator>
void __inplace_stable_sort(RandomAccessIterator first,
RandomAccessIterator last) {
if (last - first < ) {
__insertion_sort(first, last);
return;
}
RandomAccessIterator middle = first + (last - first) / ;
__inplace_stable_sort(first, middle);
__inplace_stable_sort(middle, last);
__merge_without_buffer(first, middle, last, middle - first, last - middle);
} template <class RandomAccessIterator, class Compare>
void __inplace_stable_sort(RandomAccessIterator first,
RandomAccessIterator last, Compare comp) {
if (last - first < ) {
__insertion_sort(first, last, comp);
return;
}
RandomAccessIterator middle = first + (last - first) / ;
__inplace_stable_sort(first, middle, comp);
__inplace_stable_sort(middle, last, comp);
__merge_without_buffer(first, middle, last, middle - first,
last - middle, comp);
} template <class RandomAccessIterator1, class RandomAccessIterator2,
class Distance>
void __merge_sort_loop(RandomAccessIterator1 first,
RandomAccessIterator1 last,
RandomAccessIterator2 result, Distance step_size) {
Distance two_step = * step_size; while (last - first >= two_step) {
result = merge(first, first + step_size,
first + step_size, first + two_step, result);
first += two_step;
} step_size = min(Distance(last - first), step_size);
merge(first, first + step_size, first + step_size, last, result);
} template <class RandomAccessIterator1, class RandomAccessIterator2,
class Distance, class Compare>
void __merge_sort_loop(RandomAccessIterator1 first,
RandomAccessIterator1 last,
RandomAccessIterator2 result, Distance step_size,
Compare comp) {
Distance two_step = * step_size; while (last - first >= two_step) {
result = merge(first, first + step_size,
first + step_size, first + two_step, result, comp);
first += two_step;
}
step_size = min(Distance(last - first), step_size); merge(first, first + step_size, first + step_size, last, result, comp);
} const int __stl_chunk_size = ; template <class RandomAccessIterator, class Distance>
void __chunk_insertion_sort(RandomAccessIterator first,
RandomAccessIterator last, Distance chunk_size) {
while (last - first >= chunk_size) {
__insertion_sort(first, first + chunk_size);
first += chunk_size;
}
__insertion_sort(first, last);
} template <class RandomAccessIterator, class Distance, class Compare>
void __chunk_insertion_sort(RandomAccessIterator first,
RandomAccessIterator last,
Distance chunk_size, Compare comp) {
while (last - first >= chunk_size) {
__insertion_sort(first, first + chunk_size, comp);
first += chunk_size;
}
__insertion_sort(first, last, comp);
} template <class RandomAccessIterator, class Pointer, class Distance>
void __merge_sort_with_buffer(RandomAccessIterator first,
RandomAccessIterator last,
Pointer buffer, Distance*) {
Distance len = last - first;
Pointer buffer_last = buffer + len; Distance step_size = __stl_chunk_size;
__chunk_insertion_sort(first, last, step_size); while (step_size < len) {
__merge_sort_loop(first, last, buffer, step_size);
step_size *= ;
__merge_sort_loop(buffer, buffer_last, first, step_size);
step_size *= ;
}
} template <class RandomAccessIterator, class Pointer, class Distance,
class Compare>
void __merge_sort_with_buffer(RandomAccessIterator first,
RandomAccessIterator last, Pointer buffer,
Distance*, Compare comp) {
Distance len = last - first;
Pointer buffer_last = buffer + len; Distance step_size = __stl_chunk_size;
__chunk_insertion_sort(first, last, step_size, comp); while (step_size < len) {
__merge_sort_loop(first, last, buffer, step_size, comp);
step_size *= ;
__merge_sort_loop(buffer, buffer_last, first, step_size, comp);
step_size *= ;
}
} template <class RandomAccessIterator, class Pointer, class Distance>
void __stable_sort_adaptive(RandomAccessIterator first,
RandomAccessIterator last, Pointer buffer,
Distance buffer_size) {
Distance len = (last - first + ) / ;
RandomAccessIterator middle = first + len;
if (len > buffer_size) {
__stable_sort_adaptive(first, middle, buffer, buffer_size);
__stable_sort_adaptive(middle, last, buffer, buffer_size);
} else {
__merge_sort_with_buffer(first, middle, buffer, (Distance*));
__merge_sort_with_buffer(middle, last, buffer, (Distance*));
}
__merge_adaptive(first, middle, last, Distance(middle - first),
Distance(last - middle), buffer, buffer_size);
} template <class RandomAccessIterator, class Pointer, class Distance,
class Compare>
void __stable_sort_adaptive(RandomAccessIterator first,
RandomAccessIterator last, Pointer buffer,
Distance buffer_size, Compare comp) {
Distance len = (last - first + ) / ;
RandomAccessIterator middle = first + len;
if (len > buffer_size) {
__stable_sort_adaptive(first, middle, buffer, buffer_size,
comp);
__stable_sort_adaptive(middle, last, buffer, buffer_size,
comp);
} else {
__merge_sort_with_buffer(first, middle, buffer, (Distance*), comp);
__merge_sort_with_buffer(middle, last, buffer, (Distance*), comp);
}
__merge_adaptive(first, middle, last, Distance(middle - first),
Distance(last - middle), buffer, buffer_size,
comp);
} template <class RandomAccessIterator, class T, class Distance>
inline void __stable_sort_aux(RandomAccessIterator first,
RandomAccessIterator last, T*, Distance*) {
temporary_buffer<RandomAccessIterator, T> buf(first, last);
if (buf.begin() == )
__inplace_stable_sort(first, last);
else
__stable_sort_adaptive(first, last, buf.begin(), Distance(buf.size()));
} template <class RandomAccessIterator, class T, class Distance, class Compare>
inline void __stable_sort_aux(RandomAccessIterator first,
RandomAccessIterator last, T*, Distance*,
Compare comp) {
temporary_buffer<RandomAccessIterator, T> buf(first, last);
if (buf.begin() == )
__inplace_stable_sort(first, last, comp);
else
__stable_sort_adaptive(first, last, buf.begin(), Distance(buf.size()),
comp);
} template <class RandomAccessIterator>
inline void stable_sort(RandomAccessIterator first,
RandomAccessIterator last) {
__stable_sort_aux(first, last, value_type(first), distance_type(first));
} template <class RandomAccessIterator, class Compare>
inline void stable_sort(RandomAccessIterator first,
RandomAccessIterator last, Compare comp) {
__stable_sort_aux(first, last, value_type(first), distance_type(first),
comp);
} template <class RandomAccessIterator, class T>
void __partial_sort(RandomAccessIterator first, RandomAccessIterator middle,
RandomAccessIterator last, T*) {
make_heap(first, middle);
for (RandomAccessIterator i = middle; i < last; ++i)
if (*i < *first)
__pop_heap(first, middle, i, T(*i), distance_type(first));
sort_heap(first, middle);
} // 只保证[first, middle)有序, 效率至上时使用
template <class RandomAccessIterator>
inline void partial_sort(RandomAccessIterator first,
RandomAccessIterator middle,
RandomAccessIterator last)
{
__partial_sort(first, middle, last, value_type(first));
} template <class RandomAccessIterator, class T, class Compare>
void __partial_sort(RandomAccessIterator first, RandomAccessIterator middle,
RandomAccessIterator last, T*, Compare comp) {
make_heap(first, middle, comp);
for (RandomAccessIterator i = middle; i < last; ++i)
if (comp(*i, *first))
__pop_heap(first, middle, i, T(*i), comp, distance_type(first));
sort_heap(first, middle, comp);
} template <class RandomAccessIterator, class Compare>
inline void partial_sort(RandomAccessIterator first,
RandomAccessIterator middle,
RandomAccessIterator last, Compare comp) {
__partial_sort(first, middle, last, value_type(first), comp);
} template <class InputIterator, class RandomAccessIterator, class Distance,
class T>
RandomAccessIterator __partial_sort_copy(InputIterator first,
InputIterator last,
RandomAccessIterator result_first,
RandomAccessIterator result_last,
Distance*, T*) {
if (result_first == result_last) return result_last;
RandomAccessIterator result_real_last = result_first;
while(first != last && result_real_last != result_last) {
*result_real_last = *first;
++result_real_last;
++first;
}
make_heap(result_first, result_real_last);
while (first != last) {
if (*first < *result_first)
__adjust_heap(result_first, Distance(),
Distance(result_real_last - result_first), T(*first));
++first;
}
sort_heap(result_first, result_real_last);
return result_real_last;
} template <class InputIterator, class RandomAccessIterator>
inline RandomAccessIterator
partial_sort_copy(InputIterator first, InputIterator last,
RandomAccessIterator result_first,
RandomAccessIterator result_last) {
return __partial_sort_copy(first, last, result_first, result_last,
distance_type(result_first), value_type(first));
} template <class InputIterator, class RandomAccessIterator, class Compare,
class Distance, class T>
RandomAccessIterator __partial_sort_copy(InputIterator first,
InputIterator last,
RandomAccessIterator result_first,
RandomAccessIterator result_last,
Compare comp, Distance*, T*) {
if (result_first == result_last) return result_last;
RandomAccessIterator result_real_last = result_first;
while(first != last && result_real_last != result_last) {
*result_real_last = *first;
++result_real_last;
++first;
}
make_heap(result_first, result_real_last, comp);
while (first != last) {
if (comp(*first, *result_first))
__adjust_heap(result_first, Distance(),
Distance(result_real_last - result_first), T(*first),
comp);
++first;
}
sort_heap(result_first, result_real_last, comp);
return result_real_last;
} template <class InputIterator, class RandomAccessIterator, class Compare>
inline RandomAccessIterator
partial_sort_copy(InputIterator first, InputIterator last,
RandomAccessIterator result_first,
RandomAccessIterator result_last, Compare comp) {
return __partial_sort_copy(first, last, result_first, result_last, comp,
distance_type(result_first), value_type(first));
} template <class RandomAccessIterator, class T>
void __nth_element(RandomAccessIterator first, RandomAccessIterator nth,
RandomAccessIterator last, T*) {
while (last - first > ) {
RandomAccessIterator cut = __unguarded_partition
(first, last, T(__median(*first, *(first + (last - first)/),
*(last - ))));
if (cut <= nth)
first = cut;
else
last = cut;
}
__insertion_sort(first, last);
} template <class RandomAccessIterator>
inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth,
RandomAccessIterator last) {
__nth_element(first, nth, last, value_type(first));
} template <class RandomAccessIterator, class T, class Compare>
void __nth_element(RandomAccessIterator first, RandomAccessIterator nth,
RandomAccessIterator last, T*, Compare comp) {
while (last - first > ) {
RandomAccessIterator cut = __unguarded_partition
(first, last, T(__median(*first, *(first + (last - first)/),
*(last - ), comp)), comp);
if (cut <= nth)
first = cut;
else
last = cut;
}
__insertion_sort(first, last, comp);
} template <class RandomAccessIterator, class Compare>
inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth,
RandomAccessIterator last, Compare comp) {
__nth_element(first, nth, last, value_type(first), comp);
} template <class ForwardIterator, class T, class Distance>
ForwardIterator __lower_bound(ForwardIterator first, ForwardIterator last,
const T& value, Distance*,
forward_iterator_tag) {
Distance len = ;
distance(first, last, len);
Distance half;
ForwardIterator middle; while (len > ) {
half = len >> ;
middle = first;
advance(middle, half);
if (*middle < value) {
first = middle;
++first;
len = len - half - ;
}
else
len = half;
}
return first;
} template <class RandomAccessIterator, class T, class Distance>
RandomAccessIterator __lower_bound(RandomAccessIterator first,
RandomAccessIterator last, const T& value,
Distance*, random_access_iterator_tag) {
Distance len = last - first;
Distance half;
RandomAccessIterator middle; while (len > ) {
half = len >> ;
middle = first + half;
if (*middle < value) {
first = middle + ;
len = len - half - ;
}
else
len = half;
}
return first;
} // 用于有序区间, 返回第一个大于value的位置
// 同样为了效率, 要进行函数派发
template <class ForwardIterator, class T>
inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last,
const T& value)
{
return __lower_bound(first, last, value, distance_type(first),
iterator_category(first));
} template <class ForwardIterator, class T, class Compare, class Distance>
ForwardIterator __lower_bound(ForwardIterator first, ForwardIterator last,
const T& value, Compare comp, Distance*,
forward_iterator_tag) {
Distance len = ;
distance(first, last, len);
Distance half;
ForwardIterator middle; while (len > ) {
half = len >> ;
middle = first;
advance(middle, half);
if (comp(*middle, value)) {
first = middle;
++first;
len = len - half - ;
}
else
len = half;
}
return first;
} template <class RandomAccessIterator, class T, class Compare, class Distance>
RandomAccessIterator __lower_bound(RandomAccessIterator first,
RandomAccessIterator last,
const T& value, Compare comp, Distance*,
random_access_iterator_tag) {
Distance len = last - first;
Distance half;
RandomAccessIterator middle; while (len > ) {
half = len >> ;
middle = first + half;
if (comp(*middle, value)) {
first = middle + ;
len = len - half - ;
}
else
len = half;
}
return first;
} template <class ForwardIterator, class T, class Compare>
inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last,
const T& value, Compare comp) {
return __lower_bound(first, last, value, comp, distance_type(first),
iterator_category(first));
} template <class ForwardIterator, class T, class Distance>
ForwardIterator __upper_bound(ForwardIterator first, ForwardIterator last,
const T& value, Distance*,
forward_iterator_tag) {
Distance len = ;
distance(first, last, len);
Distance half;
ForwardIterator middle; while (len > ) {
half = len >> ;
middle = first;
advance(middle, half);
if (value < *middle)
len = half;
else {
first = middle;
++first;
len = len - half - ;
}
}
return first;
} template <class RandomAccessIterator, class T, class Distance>
RandomAccessIterator __upper_bound(RandomAccessIterator first,
RandomAccessIterator last, const T& value,
Distance*, random_access_iterator_tag) {
Distance len = last - first;
Distance half;
RandomAccessIterator middle; while (len > ) {
half = len >> ;
middle = first + half;
if (value < *middle)
len = half;
else {
first = middle + ;
len = len - half - ;
}
}
return first;
} template <class ForwardIterator, class T>
inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last,
const T& value) {
return __upper_bound(first, last, value, distance_type(first),
iterator_category(first));
} template <class ForwardIterator, class T, class Compare, class Distance>
ForwardIterator __upper_bound(ForwardIterator first, ForwardIterator last,
const T& value, Compare comp, Distance*,
forward_iterator_tag) {
Distance len = ;
distance(first, last, len);
Distance half;
ForwardIterator middle; while (len > ) {
half = len >> ;
middle = first;
advance(middle, half);
if (comp(value, *middle))
len = half;
else {
first = middle;
++first;
len = len - half - ;
}
}
return first;
} template <class RandomAccessIterator, class T, class Compare, class Distance>
RandomAccessIterator __upper_bound(RandomAccessIterator first,
RandomAccessIterator last,
const T& value, Compare comp, Distance*,
random_access_iterator_tag) {
Distance len = last - first;
Distance half;
RandomAccessIterator middle; while (len > ) {
half = len >> ;
middle = first + half;
if (comp(value, *middle))
len = half;
else {
first = middle + ;
len = len - half - ;
}
}
return first;
} template <class ForwardIterator, class T, class Compare>
inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last,
const T& value, Compare comp) {
return __upper_bound(first, last, value, comp, distance_type(first),
iterator_category(first));
} template <class ForwardIterator, class T, class Distance>
pair<ForwardIterator, ForwardIterator>
__equal_range(ForwardIterator first, ForwardIterator last, const T& value,
Distance*, forward_iterator_tag) {
Distance len = ;
distance(first, last, len);
Distance half;
ForwardIterator middle, left, right; while (len > ) {
half = len >> ;
middle = first;
advance(middle, half);
if (*middle < value) {
first = middle;
++first;
len = len - half - ;
}
else if (value < *middle)
len = half;
else {
left = lower_bound(first, middle, value);
advance(first, len);
right = upper_bound(++middle, first, value);
return pair<ForwardIterator, ForwardIterator>(left, right);
}
}
return pair<ForwardIterator, ForwardIterator>(first, first);
} template <class RandomAccessIterator, class T, class Distance>
pair<RandomAccessIterator, RandomAccessIterator>
__equal_range(RandomAccessIterator first, RandomAccessIterator last,
const T& value, Distance*, random_access_iterator_tag) {
Distance len = last - first;
Distance half;
RandomAccessIterator middle, left, right; while (len > ) {
half = len >> ;
middle = first + half;
if (*middle < value) {
first = middle + ;
len = len - half - ;
}
else if (value < *middle)
len = half;
else {
left = lower_bound(first, middle, value);
right = upper_bound(++middle, first + len, value);
return pair<RandomAccessIterator, RandomAccessIterator>(left,
right);
}
}
return pair<RandomAccessIterator, RandomAccessIterator>(first, first);
} template <class ForwardIterator, class T>
inline pair<ForwardIterator, ForwardIterator>
equal_range(ForwardIterator first, ForwardIterator last, const T& value) {
return __equal_range(first, last, value, distance_type(first),
iterator_category(first));
} template <class ForwardIterator, class T, class Compare, class Distance>
pair<ForwardIterator, ForwardIterator>
__equal_range(ForwardIterator first, ForwardIterator last, const T& value,
Compare comp, Distance*, forward_iterator_tag) {
Distance len = ;
distance(first, last, len);
Distance half;
ForwardIterator middle, left, right; while (len > ) {
half = len >> ;
middle = first;
advance(middle, half);
if (comp(*middle, value)) {
first = middle;
++first;
len = len - half - ;
}
else if (comp(value, *middle))
len = half;
else {
left = lower_bound(first, middle, value, comp);
advance(first, len);
right = upper_bound(++middle, first, value, comp);
return pair<ForwardIterator, ForwardIterator>(left, right);
}
}
return pair<ForwardIterator, ForwardIterator>(first, first);
} template <class RandomAccessIterator, class T, class Compare, class Distance>
pair<RandomAccessIterator, RandomAccessIterator>
__equal_range(RandomAccessIterator first, RandomAccessIterator last,
const T& value, Compare comp, Distance*,
random_access_iterator_tag) {
Distance len = last - first;
Distance half;
RandomAccessIterator middle, left, right; while (len > ) {
half = len >> ;
middle = first + half;
if (comp(*middle, value)) {
first = middle + ;
len = len - half - ;
}
else if (comp(value, *middle))
len = half;
else {
left = lower_bound(first, middle, value, comp);
right = upper_bound(++middle, first + len, value, comp);
return pair<RandomAccessIterator, RandomAccessIterator>(left,
right);
}
}
return pair<RandomAccessIterator, RandomAccessIterator>(first, first);
} template <class ForwardIterator, class T, class Compare>
inline pair<ForwardIterator, ForwardIterator>
equal_range(ForwardIterator first, ForwardIterator last, const T& value,
Compare comp) {
return __equal_range(first, last, value, comp, distance_type(first),
iterator_category(first));
} // 用于有序区间的二分查找, 不知道的赶快去学数据结构
template <class ForwardIterator, class T>
bool binary_search(ForwardIterator first, ForwardIterator last,
const T& value) {
ForwardIterator i = lower_bound(first, last, value);
return i != last && !(value < *i);
} template <class ForwardIterator, class T, class Compare>
bool binary_search(ForwardIterator first, ForwardIterator last, const T& value,
Compare comp) {
ForwardIterator i = lower_bound(first, last, value, comp);
return i != last && !comp(value, *i);
} // 将两个有序区间合并起来, 并保证其也有序
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator merge(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result)
{
while (first1 != last1 && first2 != last2) {
if (*first2 < *first1) {
*result = *first2;
++first2;
}
else {
*result = *first1;
++first1;
}
++result;
}
return copy(first2, last2, copy(first1, last1, result));
} template <class InputIterator1, class InputIterator2, class OutputIterator,
class Compare>
OutputIterator merge(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result, Compare comp)
{
while (first1 != last1 && first2 != last2) {
if (comp(*first2, *first1)) {
*result = *first2;
++first2;
}
else {
*result = *first1;
++first1;
}
++result;
}
return copy(first2, last2, copy(first1, last1, result));
} template <class BidirectionalIterator, class Distance>
void __merge_without_buffer(BidirectionalIterator first,
BidirectionalIterator middle,
BidirectionalIterator last,
Distance len1, Distance len2) {
if (len1 == || len2 == ) return;
if (len1 + len2 == ) {
if (*middle < *first) iter_swap(first, middle);
return;
}
BidirectionalIterator first_cut = first;
BidirectionalIterator second_cut = middle;
Distance len11 = ;
Distance len22 = ;
if (len1 > len2) {
len11 = len1 / ;
advance(first_cut, len11);
second_cut = lower_bound(middle, last, *first_cut);
distance(middle, second_cut, len22);
}
else {
len22 = len2 / ;
advance(second_cut, len22);
first_cut = upper_bound(first, middle, *second_cut);
distance(first, first_cut, len11);
}
rotate(first_cut, middle, second_cut);
BidirectionalIterator new_middle = first_cut;
advance(new_middle, len22);
__merge_without_buffer(first, first_cut, new_middle, len11, len22);
__merge_without_buffer(new_middle, second_cut, last, len1 - len11,
len2 - len22);
} template <class BidirectionalIterator, class Distance, class Compare>
void __merge_without_buffer(BidirectionalIterator first,
BidirectionalIterator middle,
BidirectionalIterator last,
Distance len1, Distance len2, Compare comp) {
if (len1 == || len2 == ) return;
if (len1 + len2 == ) {
if (comp(*middle, *first)) iter_swap(first, middle);
return;
}
BidirectionalIterator first_cut = first;
BidirectionalIterator second_cut = middle;
Distance len11 = ;
Distance len22 = ;
if (len1 > len2) {
len11 = len1 / ;
advance(first_cut, len11);
second_cut = lower_bound(middle, last, *first_cut, comp);
distance(middle, second_cut, len22);
}
else {
len22 = len2 / ;
advance(second_cut, len22);
first_cut = upper_bound(first, middle, *second_cut, comp);
distance(first, first_cut, len11);
}
rotate(first_cut, middle, second_cut);
BidirectionalIterator new_middle = first_cut;
advance(new_middle, len22);
__merge_without_buffer(first, first_cut, new_middle, len11, len22, comp);
__merge_without_buffer(new_middle, second_cut, last, len1 - len11,
len2 - len22, comp);
} template <class BidirectionalIterator1, class BidirectionalIterator2,
class Distance>
BidirectionalIterator1 __rotate_adaptive(BidirectionalIterator1 first,
BidirectionalIterator1 middle,
BidirectionalIterator1 last,
Distance len1, Distance len2,
BidirectionalIterator2 buffer,
Distance buffer_size) {
BidirectionalIterator2 buffer_end;
if (len1 > len2 && len2 <= buffer_size) {
buffer_end = copy(middle, last, buffer);
copy_backward(first, middle, last);
return copy(buffer, buffer_end, first);
} else if (len1 <= buffer_size) {
buffer_end = copy(first, middle, buffer);
copy(middle, last, first);
return copy_backward(buffer, buffer_end, last);
} else {
rotate(first, middle, last);
advance(first, len2);
return first;
}
} template <class BidirectionalIterator1, class BidirectionalIterator2,
class BidirectionalIterator3>
BidirectionalIterator3 __merge_backward(BidirectionalIterator1 first1,
BidirectionalIterator1 last1,
BidirectionalIterator2 first2,
BidirectionalIterator2 last2,
BidirectionalIterator3 result) {
if (first1 == last1) return copy_backward(first2, last2, result);
if (first2 == last2) return copy_backward(first1, last1, result);
--last1;
--last2;
while (true) {
if (*last2 < *last1) {
*--result = *last1;
if (first1 == last1) return copy_backward(first2, ++last2, result);
--last1;
}
else {
*--result = *last2;
if (first2 == last2) return copy_backward(first1, ++last1, result);
--last2;
}
}
} template <class BidirectionalIterator1, class BidirectionalIterator2,
class BidirectionalIterator3, class Compare>
BidirectionalIterator3 __merge_backward(BidirectionalIterator1 first1,
BidirectionalIterator1 last1,
BidirectionalIterator2 first2,
BidirectionalIterator2 last2,
BidirectionalIterator3 result,
Compare comp) {
if (first1 == last1) return copy_backward(first2, last2, result);
if (first2 == last2) return copy_backward(first1, last1, result);
--last1;
--last2;
while (true) {
if (comp(*last2, *last1)) {
*--result = *last1;
if (first1 == last1) return copy_backward(first2, ++last2, result);
--last1;
}
else {
*--result = *last2;
if (first2 == last2) return copy_backward(first1, ++last1, result);
--last2;
}
}
} template <class BidirectionalIterator, class Distance, class Pointer>
void __merge_adaptive(BidirectionalIterator first,
BidirectionalIterator middle,
BidirectionalIterator last, Distance len1, Distance len2,
Pointer buffer, Distance buffer_size) {
if (len1 <= len2 && len1 <= buffer_size) {
Pointer end_buffer = copy(first, middle, buffer);
merge(buffer, end_buffer, middle, last, first);
}
else if (len2 <= buffer_size) {
Pointer end_buffer = copy(middle, last, buffer);
__merge_backward(first, middle, buffer, end_buffer, last);
}
else {
BidirectionalIterator first_cut = first;
BidirectionalIterator second_cut = middle;
Distance len11 = ;
Distance len22 = ;
if (len1 > len2) {
len11 = len1 / ;
advance(first_cut, len11);
second_cut = lower_bound(middle, last, *first_cut);
distance(middle, second_cut, len22);
}
else {
len22 = len2 / ;
advance(second_cut, len22);
first_cut = upper_bound(first, middle, *second_cut);
distance(first, first_cut, len11);
}
BidirectionalIterator new_middle =
__rotate_adaptive(first_cut, middle, second_cut, len1 - len11,
len22, buffer, buffer_size);
__merge_adaptive(first, first_cut, new_middle, len11, len22, buffer,
buffer_size);
__merge_adaptive(new_middle, second_cut, last, len1 - len11,
len2 - len22, buffer, buffer_size);
}
} template <class BidirectionalIterator, class Distance, class Pointer,
class Compare>
void __merge_adaptive(BidirectionalIterator first,
BidirectionalIterator middle,
BidirectionalIterator last, Distance len1, Distance len2,
Pointer buffer, Distance buffer_size, Compare comp) {
if (len1 <= len2 && len1 <= buffer_size) {
Pointer end_buffer = copy(first, middle, buffer);
merge(buffer, end_buffer, middle, last, first, comp);
}
else if (len2 <= buffer_size) {
Pointer end_buffer = copy(middle, last, buffer);
__merge_backward(first, middle, buffer, end_buffer, last, comp);
}
else {
BidirectionalIterator first_cut = first;
BidirectionalIterator second_cut = middle;
Distance len11 = ;
Distance len22 = ;
if (len1 > len2) {
len11 = len1 / ;
advance(first_cut, len11);
second_cut = lower_bound(middle, last, *first_cut, comp);
distance(middle, second_cut, len22);
}
else {
len22 = len2 / ;
advance(second_cut, len22);
first_cut = upper_bound(first, middle, *second_cut, comp);
distance(first, first_cut, len11);
}
BidirectionalIterator new_middle =
__rotate_adaptive(first_cut, middle, second_cut, len1 - len11,
len22, buffer, buffer_size);
__merge_adaptive(first, first_cut, new_middle, len11, len22, buffer,
buffer_size, comp);
__merge_adaptive(new_middle, second_cut, last, len1 - len11,
len2 - len22, buffer, buffer_size, comp);
}
} template <class BidirectionalIterator, class T, class Distance>
inline void __inplace_merge_aux(BidirectionalIterator first,
BidirectionalIterator middle,
BidirectionalIterator last, T*, Distance*) {
Distance len1 = ;
distance(first, middle, len1);
Distance len2 = ;
distance(middle, last, len2); temporary_buffer<BidirectionalIterator, T> buf(first, last);
if (buf.begin() == )
__merge_without_buffer(first, middle, last, len1, len2);
else
__merge_adaptive(first, middle, last, len1, len2,
buf.begin(), Distance(buf.size()));
} template <class BidirectionalIterator, class T, class Distance, class Compare>
inline void __inplace_merge_aux(BidirectionalIterator first,
BidirectionalIterator middle,
BidirectionalIterator last, T*, Distance*,
Compare comp) {
Distance len1 = ;
distance(first, middle, len1);
Distance len2 = ;
distance(middle, last, len2); temporary_buffer<BidirectionalIterator, T> buf(first, last);
if (buf.begin() == )
__merge_without_buffer(first, middle, last, len1, len2, comp);
else
__merge_adaptive(first, middle, last, len1, len2,
buf.begin(), Distance(buf.size()),
comp);
} template <class BidirectionalIterator>
inline void inplace_merge(BidirectionalIterator first,
BidirectionalIterator middle,
BidirectionalIterator last) {
if (first == middle || middle == last) return;
__inplace_merge_aux(first, middle, last, value_type(first),
distance_type(first));
} template <class BidirectionalIterator, class Compare>
inline void inplace_merge(BidirectionalIterator first,
BidirectionalIterator middle,
BidirectionalIterator last, Compare comp) {
if (first == middle || middle == last) return;
__inplace_merge_aux(first, middle, last, value_type(first),
distance_type(first), comp);
} // 判断[first2, last2)是否包含在[first1, last1)中,
// 注意: 两个区间要保证有序, 如果容器是降序排列, 那么要使用另一个版本,
// 并使用greater<>()来比较
template <class InputIterator1, class InputIterator2>
bool includes(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2)
{
while (first1 != last1 && first2 != last2)
if (*first2 < *first1)
return false;
else if(*first1 < *first2)
++first1;
else
++first1, ++first2; return first2 == last2;
} // 除了自己指定判别式, 其余同上
template <class InputIterator1, class InputIterator2, class Compare>
bool includes(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2, Compare comp)
{
while (first1 != last1 && first2 != last2)
if (comp(*first2, *first1))
return false;
else if(comp(*first1, *first2))
++first1;
else
++first1, ++first2; return first2 == last2;
} ////////////////////////////////////////////////////////////////////////////////
// 四个集合相关算法
//////////////////////////////////////////////////////////////////////////////// // 求两个集合的的并集, 和数学定义的并集有一些不一样
// 对于两个集合S1[first1, last1)和S2[first2, last2)
// 假设其中k元素在S1中出现n1次, 在S2中出现n2次
// 那么求出的并集选取max(n1, n2)为并集内k元素个数
// 注意: 集合相关操作均要求区间有序, 后面不再强调
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result)
{
// 先进行历遍操作
while (first1 != last1 && first2 != last2) {
// 这里把现在能确定的并集先加入到result中
// 先把较小的加入到结果中, 否则如果相等, 那么也要加入
if (*first1 < *first2) {
*result = *first1;
++first1;
}
else if (*first2 < *first1) {
*result = *first2;
++first2;
}
else {
*result = *first1;
++first1;
++first2;
}
++result;
} // 将剩余的元素加入到并集中
return copy(first2, last2, copy(first1, last1, result));
} // 使用用户指定的二元比较判别式, 其余同上面
template <class InputIterator1, class InputIterator2, class OutputIterator,
class Compare>
OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result, Compare comp)
{
while (first1 != last1 && first2 != last2) {
if (comp(*first1, *first2)) {
*result = *first1;
++first1;
}
else if (comp(*first2, *first1)) {
*result = *first2;
++first2;
}
else {
*result = *first1;
++first1;
++first2;
}
++result;
}
return copy(first2, last2, copy(first1, last1, result));
} // 求两个集合的的交集, 和数学定义的并集有一些不一样
// 对于两个集合S1[first1, last1)和S2[first2, last2)
// 假设其中k元素在S1中出现n1次, 在S2中出现n2次
// 那么求出的交集选取min(n1, n2)为交集内k元素个数
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result)
{
// 算法很简单, 不进行说明
while (first1 != last1 && first2 != last2)
if (*first1 < *first2)
++first1;
else if (*first2 < *first1)
++first2;
else {
*result = *first1;
++first1;
++first2;
++result;
}
return result;
} // 使用用户指定的二元比较判别式, 其余同上面
template <class InputIterator1, class InputIterator2, class OutputIterator,
class Compare>
OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result, Compare comp)
{
while (first1 != last1 && first2 != last2)
if (comp(*first1, *first2))
++first1;
else if (comp(*first2, *first1))
++first2;
else {
*result = *first1;
++first1;
++first2;
++result;
}
return result;
} // 求两个集合的的差集, 和数学定义的并集有一些不一样
// 对于两个集合S1[first1, last1)和S2[first2, last2)
// 假设其中k元素在S1中出现n1次, 在S2中出现n2次
// 那么求出的差集选取max(n1 - n2, 0)为差集内k元素个数
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result)
{
while (first1 != last1 && first2 != last2)
if (*first1 < *first2) { // 找到了一个合适的元素, 加入到结果中
*result = *first1; // 向后调整迭代器
++first1;
++result;
}
else if (*first2 < *first1) // 元素不合适, 调整迭代器
++first2;
else { // 这个用来处理出现相同元素的情况
++first1;
++first2;
} // 将剩余的元素加入到结果中
return copy(first1, last1, result);
} // 使用用户指定的二元比较判别式, 其余同上面
template <class InputIterator1, class InputIterator2, class OutputIterator,
class Compare>
OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result, Compare comp) {
while (first1 != last1 && first2 != last2)
if (comp(*first1, *first2)) {
*result = *first1;
++first1;
++result;
}
else if (comp(*first2, *first1))
++first2;
else {
++first1;
++first2;
}
return copy(first1, last1, result);
} // 求两个集合的的对称差集, 和数学定义的并集有一些不一样
// 其用公式可以表示为(S1 - S2) U (S2 - S1)
// 对于两个集合S1[first1, last1)和S2[first2, last2)
// 假设其中k元素在S1中出现n1次, 在S2中出现n2次
// 那么结果中会出现|n1 - n2|个k元素
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_symmetric_difference(InputIterator1 first1,
InputIterator1 last1,
InputIterator2 first2,
InputIterator2 last2,
OutputIterator result)
{
// 算法和上面的差不多, 不解释
while (first1 != last1 && first2 != last2)
if (*first1 < *first2) {
*result = *first1;
++first1;
++result;
}
else if (*first2 < *first1) {
*result = *first2;
++first2;
++result;
}
else {
++first1;
++first2;
} return copy(first2, last2, copy(first1, last1, result));
} // 使用用户指定的二元比较判别式, 其余同上面
template <class InputIterator1, class InputIterator2, class OutputIterator,
class Compare>
OutputIterator set_symmetric_difference(InputIterator1 first1,
InputIterator1 last1,
InputIterator2 first2,
InputIterator2 last2,
OutputIterator result, Compare comp)
{
while (first1 != last1 && first2 != last2)
if (comp(*first1, *first2)) {
*result = *first1;
++first1;
++result;
}
else if (comp(*first2, *first1)) {
*result = *first2;
++first2;
++result;
}
else {
++first1;
++first2;
}
return copy(first2, last2, copy(first1, last1, result));
} // 查找指定区间内最大的元素
template <class ForwardIterator>
ForwardIterator max_element(ForwardIterator first, ForwardIterator last)
{
if (first == last) return first;
ForwardIterator result = first;
while (++first != last)
if (*result < *first) result = first;
return result;
} // 使用用户指定的二元比较判别式, 其余同上面
template <class ForwardIterator, class Compare>
ForwardIterator max_element(ForwardIterator first, ForwardIterator last,
Compare comp)
{
if (first == last) return first;
ForwardIterator result = first;
while (++first != last)
if (comp(*result, *first)) result = first;
return result;
} // 查找指定区间内最小的元素
template <class ForwardIterator>
ForwardIterator min_element(ForwardIterator first, ForwardIterator last)
{
if (first == last) return first;
ForwardIterator result = first;
while (++first != last)
if (*first < *result) result = first;
return result;
} template <class ForwardIterator, class Compare>
ForwardIterator min_element(ForwardIterator first, ForwardIterator last,
Compare comp)
{
if (first == last) return first;
ForwardIterator result = first;
while (++first != last)
if (comp(*first, *result)) result = first;
return result;
} // 获取下一个全排列
template <class BidirectionalIterator>
bool next_permutation(BidirectionalIterator first,
BidirectionalIterator last)
{
if (first == last) return false;
BidirectionalIterator i = first;
++i;
if (i == last) return false;
i = last;
--i; for(;;) {
BidirectionalIterator ii = i;
--i;
if (*i < *ii) {
BidirectionalIterator j = last;
while (!(*i < *--j));
iter_swap(i, j);
reverse(ii, last);
return true;
}
if (i == first) {
reverse(first, last);
return false;
}
}
} template <class BidirectionalIterator, class Compare>
bool next_permutation(BidirectionalIterator first, BidirectionalIterator last,
Compare comp) {
if (first == last) return false;
BidirectionalIterator i = first;
++i;
if (i == last) return false;
i = last;
--i; for(;;) {
BidirectionalIterator ii = i;
--i;
if (comp(*i, *ii)) {
BidirectionalIterator j = last;
while (!comp(*i, *--j));
iter_swap(i, j);
reverse(ii, last);
return true;
}
if (i == first) {
reverse(first, last);
return false;
}
}
} template <class BidirectionalIterator>
bool prev_permutation(BidirectionalIterator first,
BidirectionalIterator last) {
if (first == last) return false;
BidirectionalIterator i = first;
++i;
if (i == last) return false;
i = last;
--i; for(;;) {
BidirectionalIterator ii = i;
--i;
if (*ii < *i) {
BidirectionalIterator j = last;
while (!(*--j < *i));
iter_swap(i, j);
reverse(ii, last);
return true;
}
if (i == first) {
reverse(first, last);
return false;
}
}
} // 获取前一个全排列
template <class BidirectionalIterator, class Compare>
bool prev_permutation(BidirectionalIterator first, BidirectionalIterator last,
Compare comp) {
if (first == last) return false;
BidirectionalIterator i = first;
++i;
if (i == last) return false;
i = last;
--i; for(;;) {
BidirectionalIterator ii = i;
--i;
if (comp(*ii, *i)) {
BidirectionalIterator j = last;
while (!comp(*--j, *i));
iter_swap(i, j);
reverse(ii, last);
return true;
}
if (i == first) {
reverse(first, last);
return false;
}
}
} // 在区间[first1, last1)内查找区间[first2, last2)第一次出现的位置
template <class InputIterator, class ForwardIterator>
InputIterator find_first_of(InputIterator first1, InputIterator last1,
ForwardIterator first2, ForwardIterator last2)
{
for ( ; first1 != last1; ++first1)
for (ForwardIterator iter = first2; iter != last2; ++iter)
if (*first1 == *iter)
return first1;
return last1;
} // 使用用户指定的判别式, 其余同上面
template <class InputIterator, class ForwardIterator, class BinaryPredicate>
InputIterator find_first_of(InputIterator first1, InputIterator last1,
ForwardIterator first2, ForwardIterator last2,
BinaryPredicate comp)
{
for ( ; first1 != last1; ++first1)
for (ForwardIterator iter = first2; iter != last2; ++iter)
if (comp(*first1, *iter))
return first1;
return last1;
} // Search [first2, last2) as a subsequence in [first1, last1). // find_end for forward iterators.
template <class ForwardIterator1, class ForwardIterator2>
ForwardIterator1 __find_end(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
forward_iterator_tag, forward_iterator_tag)
{
if (first2 == last2) // 如果查找的目标区间为空, 那么就返回last1
return last1;
else {
ForwardIterator1 result = last1;
while () {
// 查找匹配区间
ForwardIterator1 new_result = search(first1, last1, first2, last2);
if (new_result == last1) // 没找到
return result;
else { // 找到了, 准备看后面还有没有匹配区间
result = new_result;
first1 = new_result;
++first1;
}
}
}
} template <class ForwardIterator1, class ForwardIterator2,
class BinaryPredicate>
ForwardIterator1 __find_end(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
forward_iterator_tag, forward_iterator_tag,
BinaryPredicate comp)
{
if (first2 == last2)
return last1;
else {
ForwardIterator1 result = last1;
while () {
ForwardIterator1 new_result = search(first1, last1, first2, last2, comp);
if (new_result == last1)
return result;
else {
result = new_result;
first1 = new_result;
++first1;
}
}
}
} // find_end for bidirectional iterators. Requires partial specialization.
#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template <class BidirectionalIterator1, class BidirectionalIterator2>
BidirectionalIterator1
__find_end(BidirectionalIterator1 first1, BidirectionalIterator1 last1,
BidirectionalIterator2 first2, BidirectionalIterator2 last2,
bidirectional_iterator_tag, bidirectional_iterator_tag)
{
typedef reverse_iterator<BidirectionalIterator1> reviter1;
typedef reverse_iterator<BidirectionalIterator2> reviter2; reviter1 rlast1(first1);
reviter2 rlast2(first2);
reviter1 rresult = search(reviter1(last1), rlast1, reviter2(last2), rlast2); if (rresult == rlast1)
return last1;
else {
BidirectionalIterator1 result = rresult.base();
advance(result, -distance(first2, last2));
return result;
}
} // 可以逆向查找, 速度块
template <class BidirectionalIterator1, class BidirectionalIterator2,
class BinaryPredicate>
BidirectionalIterator1
__find_end(BidirectionalIterator1 first1, BidirectionalIterator1 last1,
BidirectionalIterator2 first2, BidirectionalIterator2 last2,
bidirectional_iterator_tag, bidirectional_iterator_tag,
BinaryPredicate comp)
{
typedef reverse_iterator<BidirectionalIterator1> reviter1;
typedef reverse_iterator<BidirectionalIterator2> reviter2; reviter1 rlast1(first1);
reviter2 rlast2(first2);
reviter1 rresult = search(reviter1(last1), rlast1, reviter2(last2), rlast2,
comp); if (rresult == rlast1)
return last1;
else {
BidirectionalIterator1 result = rresult.base();
advance(result, -distance(first2, last2));
return result;
}
}
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ // 在区间[first1, last1)内查找区间[first2, last2)最后一次出现的位置
template <class ForwardIterator1, class ForwardIterator2>
inline ForwardIterator1
find_end(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2)
{
// 这里根据是否能逆向查找来派发函数
#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
typedef typename iterator_traits<ForwardIterator1>::iterator_category
category1;
typedef typename iterator_traits<ForwardIterator2>::iterator_category
category2;
return __find_end(first1, last1, first2, last2, category1(), category2());
#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
return __find_end(first1, last1, first2, last2,
forward_iterator_tag(), forward_iterator_tag());
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
} // 使用用户指定的判别式, 其余同上面
template <class ForwardIterator1, class ForwardIterator2,
class BinaryPredicate>
inline ForwardIterator1
find_end(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
BinaryPredicate comp)
{
#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
typedef typename iterator_traits<ForwardIterator1>::iterator_category
category1;
typedef typename iterator_traits<ForwardIterator2>::iterator_category
category2;
return __find_end(first1, last1, first2, last2, category1(), category2(),
comp);
#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
return __find_end(first1, last1, first2, last2,
forward_iterator_tag(), forward_iterator_tag(),
comp);
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
} template <class RandomAccessIterator, class Distance>
bool __is_heap(RandomAccessIterator first, RandomAccessIterator last,
Distance*)
{
const Distance n = last - first; Distance parent = ;
for (Distance child = ; child < n; ++child) {
if (first[parent] < first[child])
return false;
if ((child & ) == )
++parent;
}
return true;
} template <class RandomAccessIterator>
inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last)
{
return __is_heap(first, last, distance_type(first));
} template <class RandomAccessIterator, class Distance, class StrictWeakOrdering>
bool __is_heap(RandomAccessIterator first, RandomAccessIterator last,
StrictWeakOrdering comp,
Distance*)
{
const Distance n = last - first; Distance parent = ;
for (Distance child = ; child < n; ++child) {
if (comp(first[parent], first[child]))
return false;
if ((child & ) == )
++parent;
}
return true;
} template <class RandomAccessIterator, class StrictWeakOrdering>
inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last,
StrictWeakOrdering comp)
{
return __is_heap(first, last, comp, distance_type(first));
} template <class ForwardIterator>
bool is_sorted(ForwardIterator first, ForwardIterator last)
{
if (first == last)
return true; ForwardIterator next = first;
for (++next; next != last; first = next, ++next) {
if (*next < *first)
return false;
} return true;
} template <class ForwardIterator, class StrictWeakOrdering>
bool is_sorted(ForwardIterator first, ForwardIterator last,
StrictWeakOrdering comp)
{
if (first == last)
return true; ForwardIterator next = first;
for (++next; next != last; first = next, ++next) {
if (comp(*next, *first))
return false;
} return true;
} #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
#pragma reset woff 1209
#endif __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_ALGO_H */ // Local Variables:
// mode:C++
// End:

stl_algo.h的更多相关文章

  1. STL源代码剖析——STL算法stl_algo.h

    前言 在前面的博文中剖析了STL的数值算法.基本算法和set集合算法.本文剖析STL其它的算法,比如排序算法.合并算法.查找算法等等.在剖析的时候.会针对函数给出一些样例说明函数的使用.源代码出自SG ...

  2. STL algorithm源代码:stl_algo.h

    <span style="font-size:18px;">// Algorithm implementation -*- C++ -*- // Copyright ( ...

  3. STL 源代码剖析 算法 stl_algo.h -- lower_bound

    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie lower_bound(应用于有序区间) ------------------------- ...

  4. STL 源代码剖析 算法 stl_algo.h -- random_shuffle

    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie random_shuffle ------------------------------- ...

  5. STL 源代码剖析 算法 stl_algo.h -- merge sort

    本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie merge sort ----------------------------------- ...

  6. STL 源代码剖析 算法 stl_algo.h -- partition

    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie partition ------------------------------------ ...

  7. STL 源代码剖析 算法 stl_algo.h -- equal_range

    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie equal_range(应用于有序区间) ------------------------- ...

  8. STL 源代码分析 算法 stl_algo.h -- includes

    本文senlie原,转载请保留此地址:http://blog.csdn.net/zhengsenlie includes(应用于有序区间) ------------------------------ ...

  9. STL 源代码分析 算法 stl_algo.h -- merge

    本文senlie原版的,转载请保留此地址:http://blog.csdn.net/zhengsenlie merge (应用于有序区间) ------------------------------ ...

随机推荐

  1. 当退出python时,是否释放全部内存

    答案是no,循环引用其他对象或引用自全局命名空间的对象的模块,在python退出时并非完全释放 另外,也不会释放c库保留的内存部分

  2. 【转】SVN使用教程总结

    看到一篇超赞的文章,原链接:http://www.cnblogs.com/armyfai/p/3985660.html SVN简介: 为什么要使用SVN? 程序员在编写程序的过程中,每个程序员都会生成 ...

  3. 值得关注的10个Python语言学习博客

    大家好,还记得我当时学习python的时候,我一直努力地寻找关于python的博客,但我发现它们的数量很少.这也是我建立这个博客的原因,向大家分享我自己学到的新知识.今天我向大家推荐10个值得我们关注 ...

  4. UI控件之UICollectionView

    UICollectionView:集合视图,是iOS6.0后出现的,与UITableView类似,优势在于可以灵活的布局cell UICollectionViewLayout:布局类,抽象类,一般定义 ...

  5. 每天一个Linux命令(62)rcp命令

        rcp代表"remote file copy"(远程文件拷贝).     (1)用法:     用法:  rcp [参数] [源文件] [目标文件]     (2)功能: ...

  6. 键盘keyCode

    字母和数字键的键码值(keyCode)   按键 键码 按键 键码 按键 键码 按键 键码 A 65 J 74 S 83 1 49 B 66 K 75 T 84 2 50 C 67 L 76 U 85 ...

  7. 在Linux系统下使用Docker以及Weave搭建Nginx反向代理

    Hi, 今天我们将会学习如何使用 Weave 和 Docker 搭建 Nginx 的反向代理/负载均衡服务器.Weave 可以创建一个虚拟网络将 Docker 容器彼此连接在一起,支持跨主机部署及自动 ...

  8. oracle 启动数据库与监听器

    1.oracle 启动数据库与监听器 1)启动数据库 oracle用户进去 oracle/oracle sqlplus / as sysdba 然后startup 退出,然后启动监听进程 2)启动监听 ...

  9. 【51nod1519】拆方块[Codeforces](dp)

    题目传送门:1519 拆方块 首先,我们可以发现,如果第i堆方块被消除,只有三种情况: 1.第i-1堆方块全部被消除: 2.第i+1堆方块全部被消除:(因为两侧的方块能够保护这一堆方块在两侧不暴露) ...

  10. 泛型学习第一天:List与IList的区别 (二)

    原文: 探讨Ilist<>与List<> 首先要了解一点的是关于接口的基础知识: 接口不能直接实例化但是接口派生出来的抽象类可以实例化所有派生出来的抽象类都可以强制转换成接口的 ...