如何在线性时间内建立稳定的二进制值?

Mar*_*dik 2 c++ algorithm stl vector c++11

让我们假设我们有一个:

class Widget;
std::vector<Widget>;
Run Code Online (Sandbox Code Playgroud)

我们有一个功能:

bool belongsToLeft(Widget w);
Run Code Online (Sandbox Code Playgroud)

我想根据这个谓词对容器进行排序.到目前为止,我虽然这个算法.它从范围的两端发展.一旦找到一对同时属于另一端的值,它就会交换它们.

template <typename TIterator, typename TPredicate>
TIterator separate(TIterator begin, TIterator end, TPredicate belongsLeft)
{
    while (true)
    {
        while (begin != end && belongsLeft(*begin))
            ++begin;
        while (begin != end && !belongsLeft(*end))
            --end;
        if (begin == end)
            return begin;
        std::swap(*begin, *end);
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是这个算法不稳定:

#include <vector>
#include <iostream>

int main()
{
    std::vector<int> numbers = {6, 5, 4, 3, 2, 1};
    separate(numbers.begin(), numbers.end(), [](int x){return x%2 == 0;});

    for (int x : numbers)
        std::cout << x << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

6
2
4
3
5
1
Run Code Online (Sandbox Code Playgroud)

如何修改此算法以保持稳定并保持线性时间?

Tem*_*Rex 8

std::stable_partition与谓词一起使用以numbers线性复杂度分成两部分

#include <algorithm>

std::stable_partition(
    numbers.begin(), numbers.end(), 
    [](int x) { return x % 2 == 0; } // or belongsToLeft()
);
Run Code Online (Sandbox Code Playgroud)

  • 如果您知道手写算法需要做什么,请考虑一个合适的名称,然后使用同义词库查找类似于标准库算法的替代名称,例如http://thesaurus.com/browse/separate,它显示为分区为一个条目 (2认同)