绝对值排序,使用自定义比较器

时间:2019-11-21 05:41:19

标签: c++ sorting lambda

背景

在一次采访中有人问我这个问题,我无法通过所有测试用例。

问题:

  

绝对值排序

     

给出一个整数数组arr,编写一个函数absSort(arr),该函数根据arr中数字的绝对值对该数组进行排序。如果两个数字的绝对值相同,请按正负号排序,负号位于正数之前。

     

示例:

     

输入:arr = [2,-7,-2,-2,0]

     

输出:[0,-2,-2,2,-7]

我的尝试

  std::sort(nums.begin(), nums.end(), [](int a, int b) {
    if(abs(a) < abs(b))
      return true;
    return a < b ? (a < 0 && abs(a) > b) : (b < 0 && abs(b) > a);
  });

我通过了一些测试用例,但不是全部通过

Input: [2,-7,-2,-2,0]
Expected: [0,-2,-2,2,-7]
Actual: [0, -2, -7, 2, -2 ]

我感觉我需要对lambda函数进行一些小的调整,但我无法弄清楚。

4 个答案:

答案 0 :(得分:4)

这可能有效

    std::sort(nums.begin(), nums.end(), [](int a, int b) {
    if(abs(a) != abs(b))
      return abs(a) < abs(b);
    return a < b;
  });

答案 1 :(得分:3)

#include<bits/stdc++.h> //#define _max 200001 //#define _max 20000001 #define _max 2000000001 using namespace std; set<int>prime; set<int>nprime; void init() { prime.insert(2); } void go_sieve() { for(int i=3;i<_max;i+=2) { if(prime.find(i)==prime.end() && nprime.find(i)==nprime.end()) { prime.insert(i); //cout << i << endl; for(int j=2*i;j<_max;j+=i) nprime.insert(j); } if(nprime.find(i)!=nprime.end()) nprime.erase(nprime.find(i)); } } void print() { set<int> ::iterator itt; printf("-------------\n"); for(itt=prime.begin();itt!=prime.end();itt++) { cout << *itt << " "; } printf("\n-------------\n"); } int main() { init(); go_sieve(); //print(); int n; scanf("%d",&n); while(n--) { int x; scanf("%d",&x); if(prime.find(x)!=prime.end()) printf("Prime\n"); else printf("Not prime\n"); } return 0; } 的比较器不是是任意二进制函数。应该establish strict weak ordering。否则,行为是不确定的。

让我们看一下比较器(以前建议,现在已更正)

std::sort

弱序的第一个属性是:

  

对于所有bool comp(int a, int b) { if (std::abs(a) != std::abs(b)) return std::abs(a) < std::abs(b); return (a < 0); } a

此属性不适用于comp(a, a) == falsea = -1

因此,此comp(-1, -1) == true并未定义弱排序,并且调用comp会导致行为不确定!

答案 2 :(得分:2)

Java,没有流/ lambda:

public int [] sort(int [] nums) {
    int temp;

    for (int i = 0; i < nums.length; i++) {
        int minIndex = i;
        for (int j = i; j < nums.length; j++) {
           if (Math.abs(nums[j]) < Math.abs(nums[minIndex])) {
              minIndex = j;
           } else if (Math.abs(nums[j]) == Math.abs(nums[minIndex])){
              if (nums[j] < nums[minIndex]) {
                 minIndex = j;
              }
           }
        }
        if (minIndex != i) {
            temp = nums[minIndex];
            nums[minIndex] = nums[i];
            nums[i] = temp;
        }

    }
    return nums;
}

答案 3 :(得分:1)

std::sort(nums.begin(), nums.end(),
    [](int a, int b) {
        if (abs(a) != abs(b))  //a & b not equal in absolute value
            return abs(a) < abs(b);
        return (a < b);       //a & b have equal absolute value -> check sign
    });

更新: 将第二个条件从return (a < b)更正为(a < 0)