【问题标题】:possible to move zeros to the end of the array using only std::sort()? [duplicate]可以仅使用 std::sort() 将零移动到数组的末尾吗? [复制]
【发布时间】:2019-01-23 00:31:31
【问题描述】:

我正在研究这个问题:

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

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

根据cplusplus.com:

排序函数的比较器函数是一个二进制函数,它接受范围内的两个元素作为参数,并返回一个可转换为布尔值的值。返回的值指示作为第一个参数传递的元素是否被认为在其定义的特定严格弱排序中位于第二个之前。

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

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

//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]

【问题讨论】:

  • 这将归结为对标准的解释。 comp 函数被声明需要强制执行严格的弱排序。很明显,comp(4, 5) 将是 true,但 comp(5, 4)是真的。这在技术上打破了严格的弱排序,但是考虑到这个用例,我不认为这种行为是相当未定义的。
  • @Chad 这是一个严格的弱命令。值45等价的 用于此所需的排序,因此以任一顺序进行比较时都应返回false。
  • 虽然没有在这个问题中直接询问,但此类任务的预期算法将是 std::partitionstd::stable_partition

标签: c++ sorting stl


【解决方案1】:

你几乎是对的。在您的比较器函数中,您必须返回 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

【讨论】:

  • 或者更简洁,就是return (a!=0) &amp;&amp; (b==0);
  • 或者只是return b==0;;
【解决方案2】:

正如 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

【讨论】:

    【解决方案3】:

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

    正确构造比较函数,然后您可以在调用std::stable_sort 时使用它来实现您想要做的事情。

    【讨论】:

      猜你喜欢
      • 2021-03-22
      • 1970-01-01
      • 1970-01-01
      • 2019-07-19
      • 1970-01-01
      • 2021-10-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-07
      相关资源
      最近更新 更多