什么是交替排序数组的最简单方法(例如:T,T,F,F,F,T,F,T,F,F,F到T,F,T,F,T,F,T,F,T ,T,T)?

时间:2016-06-01 08:07:51

标签: c++ algorithm for-loop

例如,我有一个向量

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

有没有算法可以做到?

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想法基本相同,不同之处在于此版本不需要移动元素。