我写了这个分区函数:
template <class I, class P> I partition(I beg, I end, P p)
{
I first = beg;
while(beg != end) {
if(!p(*beg))
beg++;
else {
// if(beg != first) - EDIT: add conditional to prevent swapping identical elements
std::swap(*beg, *first);
first++;
beg++;
}
}
return first;
}
我已经用一些输出对其进行了测试,但没有发现任何问题。
标准库分区函数等价于:
template <class BidirectionalIterator, class UnaryPredicate>
BidirectionalIterator partition (BidirectionalIterator first,
BidirectionalIterator last, UnaryPredicate pred)
{
while (first!=last) {
while (pred(*first)) {
++first;
if (first==last) return first;
}
do {
--last;
if (first==last) return first;
} while (!pred(*last));
swap (*first,*last);
++first;
}
return first;
}
后者似乎要复杂得多,并且有嵌套循环。我的版本有问题吗?如果不是为什么更复杂的版本?
这是使用以下谓词的一些输出:
bool greaterthantwo(double val)
{
return val > 2;
}
MAIN
std::vector<double> test{1,2,3,4,2,5,6,7,4,8,2,4,10};
std::vector<double>::iterator part = ::partition(test.begin(), test.end(), greaterthantwo);
for(const auto &ref:test)
std::cout << ref << " ";
std::cout << std::endl;
for(auto it = part; it != test.end(); it++)
std::cout << *it << " ";
std::cout << std::endl;
OUTPUT
3 4 5 6 7 4 8 4 10 2 2 2 1
2 2 2 1