我有以下矢量:
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存储为对的矢量。
答案 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);
答案 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;
}