有选择地对向量 c++ 进行排序

Selectively sort vector c++

本文关键字:排序 c++ 向量 选择地      更新时间:2023-10-16

>我有以下向量:

vector<unsigned> vec = {5, 6, 5, 4, 1, 3, 0, 4}
现在我想按奇数索引按

字典顺序对这个向量进行排序(如果奇数索引相等,则按偶数索引)。使得排序向量"vec"为:

   {0, 4, 1, 3, 5, 4, 5, 6}

我知道std::sort将完全对"vec"进行排序。是否可以使用 std::sort 有选择地对向量进行排序。同样适用于 std::lower_bound。是否可以仅使用奇数指数找到lower_bound。

我想要与对向量相同的效果。出于效率原因,我不将 vec 存储为对的向量。

使用 range-v3,您可以执行以下操作:

std::vector<unsigned> vec = {5, 6, 5, 4, 1, 3, 0, 4};
auto pair_view = ranges::view::zip(vec | ranges::view::stride(2),
                                   vec | ranges::view::drop(1) |  ranges::view::stride(2));
ranges::sort(pair_view);

演示

效率不高,但有效的解决方案是:

std::vector<std::pair<size_t,unsigned int>> temp_vec;
temp_vec.reserve(vec.size());
for(size_t i=0;i<vec.size();++i){
    temp_vec.emplace_back(i,vec[i]);
}
std::sort(temp_vec.begin(),temp_vec.end(),[](auto l,auto r){
    return /* some condition based on l.first and r.first*/;
});
std::transfrom(temp_vec.begin(),temp_vec.end(),vec.begin(),[](auto item){
     return item.second;
});
这可以

通过使用自定义迭代器调用std::sort来实现,该迭代器跳过索引,并使用自定义比较功能(如果当前比较相等,则比较相邻值)。

自定义迭代器

可以在现有迭代器之上构建。像这样的构造称为迭代器适配器。您不需要自己从头开始编写这样的迭代器适配器,因为 boost 已经完成了艰苦的工作。您可以使用boost::adaptors::strided .如果您无法使用 boost,则可以重新实现它。


不过,更简单的解决方案是使用对。或者更好的是,如果成员有合理的名称,则为结构。

不是最快的排序算法,但它有效:

#include <vector>
#include <algorithm>
int main()
{
    std::vector<unsigned> vec = { 5, 6, 5, 4, 1, 3, 0, 4 };
    if (vec.size() > 1 && vec.size() % 2 == 0)
    {
        for (size_t i1 = 0, j1 = i1 + 1; i1 < vec.size() - 1 && j1 < vec.size(); i1+=2, j1 = i1+1)
        { 
            for (size_t i2 = i1 + 2, j2 = i2 + 1; i2 < vec.size() - 1 && j2 < vec.size(); i2 += 2, j2 = i2 + 1)
            {
                if (vec[i1] > vec[i2] || (vec[i1] == vec[i2] && vec[j1] > vec[j2]))
                {
                    std::swap(vec[i1], vec[i2]);
                    std::swap(vec[j1], vec[j2]);
                }
            }
        }
    }
    return 0;
}

[关于科利鲁]