例如,我有一个向量
vector<pair<bool,int> > v={{true,1},{true,2},{false,3},{false,4},{false,5},{true,6},{false,7},{true,8},{false,9},{false,10},{false,11}};
我想对它进行排序,以便相邻元素的bool值尽可能不同(int的值不需要排序),输出应该是这样的:
0,...
1,...
0,...
1,...
.
.
.
0,...
0,...
0,...
我试过这样的事情:
sort(v.begin(),v.end());
for(int i=1;i<v.size()/2;i+=2){
iter_swap(v.begin()+i,v.end()-i);
}
但这不是我想要的输出:
0,3
1,8
0,5
1,2
0,9
0,10
0,11
1,1
0,7
1,6
0,4
有没有算法可以做到?
答案 0 :(得分:2)
对数组进行分区,如下所示:
std::vector<std::pair<bool,int> > v={{true,1},{true,2},{false,3},{false,4},{false,5},{true,6},{false,7},{true,8},{false,9},{false,10},{false,11}};
auto p = std::partition(v.begin(), v.end(), [](const auto& p) { return !p.first; });
auto it1 = v.begin();
auto it2 = p;
while(it1 != p || it2 != v.end()) {
if(it1 != p) {
std::cout << it1->first << ',' << it1->second << std::endl;
++it1;
}
if(it2 != v.end()) {
std::cout << it2->first << ',' << it2->second << std::endl;
++it2;
}
}
答案 1 :(得分:1)
我会创建一个频率数组,或者从每个部分中取一个元素。
答案 2 :(得分:0)
将所有项目移动到辅助数组,左边是T,右边是F(你甚至不需要复制布尔值)。然后以交替的方式复制回来。
稍加注意,您可以就地进行两次重组。
答案 3 :(得分:0)
你可能有两个迭代器在你的序列上游行,一个迭代器访问所有真正的对,第一个元素是true
,另一个迭代器访问对,第一个元素是false
。然后以交替顺序打印迭代器指向的值:
#include <iostream>
#include <vector>
#include <utility>
int main()
{
std::vector<std::pair<bool,int> > v={{true,1},{true,2},{false,3},{false,4},{false,5},{true,6},{false,7},{true,8},{false,9},{false,10},{false,11}};
auto isTruePair = [](std::pair<bool, int> p) { return p.first; };
auto isFalsePair = [](std::pair<bool, int> p) { return !p.first; };
auto trueIt = std::find_if( v.begin(), v.end(), isTruePair );
auto falseIt = std::find_if( v.begin(), v.end(), isFalsePair );
while ( trueIt != v.end() || falseIt != v.end() ) {
if ( falseIt != v.end() ) {
std::cout << "0," << falseIt->second << '\n';
falseIt = std::find_if( ++falseIt, v.end(), isFalsePair );
}
if ( trueIt != v.end() ) {
std::cout << "1," << trueIt->second << '\n';
trueIt = std::find_if( ++trueIt, v.end(), isTruePair );
}
}
}
我现在看到这与@ Smeeheey的答案中给出的std::partition
想法基本相同,不同之处在于此版本不需要移动元素。