我有一个包含数值的long[]
数组。我需要的是一个已排序的数组,其中包含第一个数组的索引。
例如:
输入:
long[ ] values = {1 , 3 , 2 , 5 , 4};
输出:
long[ ] SortIndex = {0 , 2 , 1 , 4 , 3}
这意味着:
values[0] < values[2] < values[1] < values[4] < values[3]
按照 SortIndex
的升序或降序并不重要。
我有一个包含数值的long[]
数组。我需要的是一个已排序的数组,其中包含第一个数组的索引。
例如:
输入:
long[ ] values = {1 , 3 , 2 , 5 , 4};
long[ ] SortIndex = {0 , 2 , 1 , 4 , 3}
values[0] < values[2] < values[1] < values[4] < values[3]
按照 SortIndex
的升序或降序并不重要。
long[] values = {1 , 3 , 2 , 5 , 4};
Map<Long, Integer> indices = new HashMap<Long, Integer>();
for (int index = 0; index < values.length; index++) {
indices.put(values[index], index);
}
long[] copy = Arrays.copyOf(values, values.length);
Arrays.sort(copy);
for (int index = 0; index < copy.length; index++) {
copy[index] = indices.get(copy[index]);
}
你的索引列表将会在copy
中。
此处有一个工作示例:http://ideone.com/A9Imz
TreeMap
添加Long
对来实现此操作,其中键是values[index]
,值是index
。
遍历映射的iterator
将产生排序索引值。
更新
看到没有被接受的答案,这里是根据对此答案的评论进行跟进后得出的代码。
long[] values = { 1 , 3 , 2 , 5 , 4 };
int[] output = new int[values.length];
Map<Long, Integer> map = new TreeMap<Long, Integer>();
for (int n = 0; n < values.length; n++) {
map.put(values[n] * values.length + n, n);
}
int n = 0;
for (Integer index: map.values()) {
output[n++] = index;
}
System.out.println(Arrays.toString(output));
输出:
[0, 2, 1, 4, 3]
当输入中包含重复内容时,该解决方案同样有效:
long[] values = { 8, 5, 3, 2, 1, 1 };
输出:
[4, 5, 3, 2, 1, 0]
sortOrder
数组作为 Integer
数组接收,第二个循环可以替换为:Integer[] output = map.values().toArray(new Integer[values.length]);
values[index] * values.length + index
作为键来使它们的映射键唯一 :-) - rsplong[] values = { 1, 3, 2, 5, 4 };
long[] indices = new long[values.length];
for (int i = 0; i < values.length; i++) {
long min = Long.MAX_VALUE;
int minIndex = 0;
for (int j = 0; j < values.length; j++) {
if (min > values[j]) {
minIndex = j;
min = values[j];
}
}
values[minIndex] = Long.MAX_VALUE;
indices[i] = minIndex;
}
System.out.println(Arrays.toString(indices));
我通过使用Java的Comparator
接口找到了另一种优雅的解决方案。即使值不唯一,它也可以正常工作:
final Long[] values = { 1, 3, 2, 5, 4, 2};
Integer[] indices = new Integer[values.length];
for (int i = 0; i < indices.length; i++) {
indices[i] = i;
}
Comparator<Integer> comparator = new Comparator<Integer>() {
@Override
public int compare(Integer arg0, Integer arg1) {
return values[arg0].compareTo(values[arg1]);
}
};
Arrays.sort(indices, comparator);
System.out.println(Arrays.toString(indices));
输出:
[0, 2, 5, 1, 4, 3]
您可以通过更改 compare()
方法中的比较顺序,将输出顺序从升序更改为降序:
public int compare(Integer arg0, Integer arg1) {
return values[arg1].compareTo(values[arg0]);
}
您还可以将 Long[]
更改为任何其他可比较数据类型。