我有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*
目前也可用于我。因此,对所有*元素进行排序,同时将其他元素保留在原来的位置。这似乎更容易做到。
答案 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()调用来实现备用解决方案。