如何只对std :: vector中的子集进行排序?

时间:2014-02-12 17:25:03

标签: c++ algorithm sorting vector

我有vector pair s:

std::vector<std::pair<std::string, Cell::Ptr>> mCells;

我想只对元素的子集进行排序(在first的{​​{1}}上)。 string方法Cell表示它是否属于此子集。

这是我最初的原因:

GetSorted()

但它不起作用,因为std::sort(mCells.begin(), mCells.end(), [](std::pair<std::string, Cell::Ptr> const &a, std::pair<std::string, Cell::Ptr> const &b) { // Only compare when both cells need to be sorted; otherwise return false // to indicate that they are already in correct order. This keeps the // non-marked cells at their original positions. if (a.second->GetSorted() && b.second->GetSorted()) { return a.first < b.first; } else { return false; } }); 当然不会比较所有组合。有时,sort行甚至不执行一次。

要定义所需的排序功能,这是一个例子。假设元素是:

return a.first < b.first

只需对* -one进行排序。但是,排序应仅应用于相邻的待排序元素。 (这就是为什么我有G* F C* A* D B E* 。)结果应该是:

a.second->GetSorted() && b.second->GetSorted()

因此,只有 A C 相邻,并进行排序。这个问题有一个简单的解决方案吗?

或者是导致以下结果的解决方案:

G* F  A* C* D  B  E*

目前也可用于我。因此,对所有*元素进行排序,同时将其他元素保留在原来的位置。这似乎更容易做到。

1 个答案:

答案 0 :(得分:4)

您需要分离查找要排序的范围并对其进行排序:

using namespace std;

auto isSorted = [](std::pair<std::string, Cell::Ptr> const &a) {
    return a.second->GetSorted();
}

auto it = begin(mCells);
const auto itEnd = end(mCells);
while (it != itEnd) {
    auto rangeStart = find_if(it, itEnd, isSorted);
    if (rangeStart == itEnd)
        break; 
    auto rangeEnd = find_if_not(rangeStart, itEnd, isSorted);
    if (distance(rangeStart, rangeEnd) > 1) { 
        // pair comparison should do the trick here
        sort(rangeStart, rangeEnd); 
    }
    it = rangeEnd;
}

刚看到你的编辑:你可以通过定义一个跳过非排序元素的自定义输入迭代器类,然后在整个“范围”上使用单个sort()调用来实现备用解决方案。