【问题标题】:Sort array of objects by any given field with counting sort使用计数排序按任何给定字段对对象数组进行排序
【发布时间】:2021-08-26 17:41:40
【问题描述】:

我正在尝试按 x、y 或 z 坐标对 Points 数组进行排序。对于基于比较的排序,这将非常干净,因为我只需指定一个自定义比较器 lambda。但是,我使用的是计数排序。

我知道如何实现代码以按 3 个坐标中的任何一个进行排序。但是,我不想复制粘贴相同的方法 3 次。有没有办法将相同的方法推广到所有 3 个领域?

这是我的 x 代码:

private static Point[] sortX(Point[] arr, int max) {
    int[] cnt = new int[max+1];
    for(Point ele : arr) cnt[ele.x]++;
    for(int i = 1;i<cnt.length; i++) cnt[i] += cnt[i-1];
    
    Point[] ret = new Point[arr.length];
    for(int i = arr.length-1; i>=0; i--)
    {
        Point ele = arr[i];
        int sortBy = ele.x;
        ret[cnt[sortBy] - 1] = ele;
        cnt[sortBy]--;
    }
    return ret;
}

我的想法是采用另一个数组作为 sortBy,长度与 arr 相同。然后我可以使用 x、y 或 z 坐标或完全使用其他东西来创建这个数组。但是,我不喜欢这样,因为在方法之外要做的事情太多了。

我的另一个想法是让 Point 有一个像这样的 get 方法:

public int get(char c) {
    if(c == 'x') return x;
    if(c == 'y') return y;
    if(c == 'z') return z;
    return -1;
}

然后我可以让计数排序接受 'x'、'y' 或 'z' 的 char 参数。

这应该很常见吧?那么常规的做法是什么呢?

【问题讨论】:

  • 您的代码仅取决于x 两行坐标。如何将标识要排序的坐标的标志传递到sortXYZ() 并检查这两行?例如,基于标志,使用cnt[ele.x]++cnt[ele.y]++cnt[ele.z]++

标签: java sorting counting-sort


【解决方案1】:

您可以将valueFunc 传递给排序方法,该方法将从Point 返回所需的值,具体取决于给定的函数。

例如

private static Point[] sortX(Point[] arr, int max, Function<Point, Integer> valueFunc) {
        int[] cnt = new int[max+1];
        for(Point ele : arr) cnt[valueFunc.apply(ele)]++;
        for(int i = 1;i<cnt.length; i++) cnt[i] += cnt[i-1];

        Point[] ret = new Point[arr.length];
        for(int i = arr.length-1; i>=0; i--)
        {
            Point ele = arr[i];
            int sortBy = valueFunc.apply(ele);
            ret[cnt[sortBy] - 1] = ele;
            cnt[sortBy]--;
        }
        return ret;
    }

用法

sortX(points, 100, p -> p.y);
sortX(points, 100, p -> p.x);
sortX(points, 100, p -> p.z);

【讨论】:

    猜你喜欢
    • 2020-12-27
    • 2015-03-11
    • 1970-01-01
    • 2011-05-16
    • 2014-10-01
    • 1970-01-01
    相关资源
    最近更新 更多