可以仅使用std :: sort()将零移动到数组的末尾?

时间:2019-01-23 00:31:31

标签: c++ sorting stl

我正在研究这个问题:

  

给出一个数组num,编写一个函数,将所有0移到它的末尾,同时保持非零元素的相对顺序。

我知道如何仅通过就地交换来回答这个问题,但是我也想看看是否有可能用std::sort来解决它。

根据cplusplus.com:

  

sort函数的比较器函数是一个Binary函数,该函数接受范围内的两个元素作为参数,并返回可转换为bool的值。返回的值指示是否以其定义的特定严格弱顺序将作为第一个参数传递的元素视为在第二个元素之前。

     

该函数不得修改其任何参数。

     

这可以是一个函数指针或一个函数对象。

//comments below are based on my understanding
static bool comp(int a, int b){
    //lambda function evaluates to true - no swap, 
    //evaluates to false -swap
    if(a==0) return false;
    if(b==0) return true;
    //if neither a nor b is 0 them do not swap
    return true;
}

void moveZeroes(vector<int>& nums) {
    sort(nums.begin(),nums.end(),comp);
}

给定的测试用例为[0,1,0,3,12]

我的输出是[12,3,1,0,0]

3 个答案:

答案 0 :(得分:5)

您几乎正确。在比较器函数中,必须返回false才能不交换它们。另外,将std::sort更改为std::stable_sort,以使值保持原始顺序。

static bool comp(int a, int b)
{
    //lambda function evaluates to true - no swap, 
    //evaluates to false -swap
    if(a==0) return false;
    if(b==0) return true;
    //if neither a nor b is 0 them do not swap
    return false;
}

void moveZeros(std::vector<int>& nums)
{
    std::stable_sort(nums.begin(),nums.end(),comp);
}

LIVE DEMO

答案 1 :(得分:1)

正如Drew Dormann指出的那样,稳定分区是正确的算法。这是代码:

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> data { 0, 1, 0, 3, 12 };

    std::stable_partition(
        data.begin(), data.end(), [](int n) { return n != 0; });

    for (auto i : data)
        cout << i << ' ';

    cout << endl;
}

输出为1 3 12 0 0

答案 2 :(得分:0)

您要使用的排序顺序只是使零比所有非零值“更大”,并且等于其他零。所有其他非零值都“小于”零,并且等于任何其他非零值。

正确构建比较功能,然后可以在调用std::stable_sort时使用它来实现您要执行的操作。