有选择地对向量c ++

时间:2017-01-24 13:27:44

标签: c++ sorting c++11 vector

我有以下矢量:

vector<unsigned> vec = {5, 6, 5, 4, 1, 3, 0, 4}

现在我想用奇数索引按字典顺序对这个向量进行排序(如果奇数索引相等,那么偶数索引)。这样排序后的矢量&#34; vec&#34;是:

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

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

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

4 个答案:

答案 0 :(得分:6)

使用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);

Demo

答案 1 :(得分:1)

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

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;
});

答案 2 :(得分:1)

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

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

但更简单的解决方案是使用对。或者更好的是,如果成员有合理的名字,那么这个结构就是一个结构。

答案 3 :(得分:0)

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

#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;
}

[On Coliru]