我有一个数组long[100] arr;
,我想"排名"数组中的元素。意思是我想知道哪一个是最小的,哪一个是最小的,依此类推。
我知道我可以制作副本,对其进行排序,然后在未排序的数组中找到排序数组中的每个元素,但这似乎是执行此简单任务的一种非常麻烦的方式。
Java中是否有一个函数可以为您提供未排序数组的顺序?
我知道在R中有两个不同的函数,sort()
和order()
,每个任务一个。
//example
long[] arr = {1983, 321, 63, 832, 455, 1466, 788, 25425, 1839}
Arrays.sort(arr); // arr = {63, 321, 455, 788, 832, 1466, 1839, 1983, 25425}
// I'm looking for a function that will give me this-
int[] order = foo(arr); // order = {7, 0, 8, 5, 3, 6, 4, 1, 2}
答案 0 :(得分:6)
你可以创建一个索引数组,然后根据long
数组中的值对其进行排序:
import java.util.*;
class Example {
static Integer[] getSortedIndexes(final long[] arr) {
Integer[] indexes = new Integer[arr.length];
for (int n = 0; n < indexes.length; ++n) {
indexes[n] = n;
}
Arrays.sort(indexes, (left, right) -> Long.compare(arr[right], arr[left]));
return indexes;
}
public static void main(String[] args) {
long[] arr = {1983, 321, 63, 832, 455, 1466, 788, 25425, 1839};
Integer[] indexes = getSortedIndexes(arr);
System.out.println(Arrays.toString(indexes));
}
}
使用您的示例输入,产生:
[7, 0, 8, 5, 3, 6, 4, 1, 2]
我不能说它很漂亮:-),但是:
Integer
个实例,而不仅仅是int
s。。如果您想要int[]
结果,则必须在结尾添加一个传递,可以是简单的for
循环,也可以是Stream#mapToInt
(更高级但更重)。
或者,如果你想在溪流上进行全面的屠宰,请SkinnyJ points out:
static int[] getSortedIndexes(final long[] arr) {
return IntStream.range(0, arr.length).boxed().sorted((right, left) -> Long.compare(arr[left], arr[right])).mapToInt(i->i).toArray();
}
答案 1 :(得分:4)
我使用TreeMap,反转键和索引。 TreeMap按提供的Comparator对迭代进行排序,因此使用Comparator.reverseOrder来获得最大到最小的排序:
int[] order(long[] arr) {
Map<Long, Integer> map = new TreeMap<>(Comparator.reverseOrder());
for(int i = 0; i < arr.length; i++) {
map.put(arr[i], i);
}
return map.values().stream().mapToInt(i->i).toArray();
}
这是使用流的单行:
int[] order(long[] arr) {
IntStream.range(0, arr.length)
.collect(() -> new TreeMap<Long, Integer>(Comparator.reverseOrder()),
(map, i) -> map.put(arr[i], i),
Map::putAll)
.values().stream().mapToInt(i->i).toArray();
}
答案 2 :(得分:1)
您也可以在一个Stream
管道中执行此操作。
public static int[] order(long... ls) {
//If ls == null then throw a NullPointerException
Objects.requireNonNull(ls);
//Generate a IntStream in range [0, ls.length[
return IntStream.range(0, ls.length)
//convert int to Integer
.boxed()
//Sort the numbers according to the value in the array
.sorted(
//Convenient function to create a Comparator.
//Same as: (left, right) -> Long.compare(ls[right], ls[left])
Comparator.comparingLong((Integer i) -> ls[i]).reversed()
//Since values are boxed (i.e. Integer) convert back to int
).mapToInt(Integer::intValue)
//Create the int array (i.e. int[])
.toArray();
}