Java数组排序:获取数组索引排序列表的快速方法

2022-09-01 02:19:12

问题:考虑以下浮点数[]:

d[i] =     1.7 -0.3  2.1  0.5

我想要的是一个int[]数组,它表示具有索引的原始数组的顺序。

s[i] =       1    3    0    2
d[s[i]] = -0.3  0.5  1.7  2.1

当然,这可以通过自定义比较器,一组排序的自定义对象来完成,或者简单地对数组进行排序,然后在原始数组中搜索索引(颤抖)。

事实上,我正在寻找的是Matlab排序函数的第二个返回参数的等效项。

有没有一种简单的方法来做到这一点(<5 LOC)?是否有不需要为每个元素分配新对象的解决方案?


更新:

感谢您的回复。不幸的是,到目前为止,所提出的任何建议都与我所希望的简单有效的解决方案相似。因此,我在JDK反馈论坛中打开了一个线程,建议添加一个新的类库函数来解决这个问题。让我们看看Sun/Oracle对这个问题的看法。

http://forums.java.net/jive/thread.jspa?threadID=62657&tstart=0


答案 1

创建索引器数组的简单解决方案:通过比较数据值对索引器进行排序:

final Integer[] idx = { 0, 1, 2, 3 };
final float[] data = { 1.7f, -0.3f,  2.1f,  0.5f };

Arrays.sort(idx, new Comparator<Integer>() {
    @Override public int compare(final Integer o1, final Integer o2) {
        return Float.compare(data[o1], data[o2]);
    }
});

答案 2

为索引创建值的 aTreeMap

    float[] array = new float[]{};
    Map<Float, Integer> map = new TreeMap<Float, Integer>();
    for (int i = 0; i < array.length; ++i) {
        map.put(array[i], i);
    }
    Collection<Integer> indices = map.values();

索引将按它们指向的浮点数排序,原始数组保持不变。如果确实有必要,则将 转换为 a 将作为练习。Collection<Integer>int[]

编辑:如注释中所述,如果浮点数组中存在重复值,则此方法不起作用。这可以通过将 变为一个虽然 这将使 for 循环的内部和最终集合的生成稍微复杂化来解决。Map<Float, Integer>Map<Float, List<Integer>>