在Java中更好地查找double[]数组中每个元素的秩
在下面的代码中,我编写了计算double[]数组中每个元素的秩的代码。例如,如果我有在Java中更好地查找double[]数组中每个元素的秩,java,arrays,sorting,rank,Java,Arrays,Sorting,Rank,在下面的代码中,我编写了计算double[]数组中每个元素的秩的代码。例如,如果我有doublearray{3,1.3,2,3},那么我发现秩为{2,0,1,2}。计算如下: 1.3是最小的,因此它得到了0级 2是下一个,所以排名1 3是下一个更大的数字,所以两个3的排名都是2 publicstaticvoidmain(){ 双[]x={3,1.3,2,3}; System.out.println(Arrays.toString(x)+“-original”); System.out.pri
double
array{3,1.3,2,3}
,那么我发现秩为{2,0,1,2}
。计算如下:
- 1.3是最小的,因此它得到了0级李>
- 2是下一个,所以排名1李>
- 3是下一个更大的数字,所以两个3的排名都是2
publicstaticvoidmain(){
双[]x={3,1.3,2,3};
System.out.println(Arrays.toString(x)+“-original”);
System.out.println(“[2,0,1,2]-应该是”);
System.out.println(Arrays.toString(find(x))+“-our-rank”);
}
私有静态int[]find(双精度[]x){
List lst=new ArrayList();
int[]rank=new int[x.length];//已唯一数组的最大长度
用于(双d:x)
if(lst.indexOf(d)==-1)//列表中只有唯一的元素
第1条增补(d);
集合。排序(lst);
对于(int i=0;i我将采用这种方法:
public static int[] findRank(double[] inp) {
int[] outp = new int[inp.length];
for(int i = 0; i < inp.length; i++) {
for(int k = 0; k < inp.length; k++) {
if(inp[k] < inp[i]) outp[i]++;
}
}
return outp;
}
publicstaticint[]find(double[]inp){
int[]outp=新的int[inp.length];
对于(int i=0;i
我只是临时想到了这个,所以我不能100%地说它是否真的比你的方式快,但我想说它看起来更好,而且你不需要依赖Collections.sort()
和列表的java实现。如果你在寻找效率,不要用list.indexOf()来寻找列表的索引
多次。在列表中查找元素的时间复杂度为O(n),如下所述
您可以使用Map
而不是List
。在Map
中按键查找元素使用O(1)复杂度。假设排序为O(n log(n)),则单个O(n)过程将生成唯一秩。使用lambda compare根据x[]对整数数组I[]进行排序(lambda compare要求I[]为整数类型).然后根据I[]和x[]生成唯一秩R[]
// return unique rank
private static int[] findRank(double[] x){
int [] R = new int[x.length];
if(x.length == 0)return R;
Integer [] I = new Integer[x.length];
for(int i = 0; i < x.length; i++)
I[i] = i;
Arrays.sort(I, (i0, i1) -> (int) Math.signum(x[i0]-x[i1]));
int j = 0;
for(int i = 0; i < x.length; i++){
if(x[I[i]] != x[I[j]])
j = i;
R[I[i]] = j;
}
return R;
}
//返回唯一秩
私有静态int[]find(双精度[]x){
int[]R=新的int[x.length];
如果(x.length==0)返回R;
整数[]I=新整数[x.length];
对于(int i=0;i(int)Math.signum(x[i0]-x[i1]);
int j=0;
对于(int i=0;i
您的代码在效率方面存在一些问题。首先也是最重要的问题是使用array.indexOf()
。在数组中查找索引需要花费O(n)。您可以创建一个Map
来代替array,并使用x.get(key)
来获取与之关联的秩。您可以在Map中定义和获取键,如下所示:
Map<Double,Integer> x = new HashMap<Double, Integer>();
x.put(3.5,0);
x.put(2.0,1);
x.put(4.1,2);
//.... and put following in loop
y=x.get(2.0); //y=1
Map x=newhashmap();
x、 put(3.5,0);
x、 put(2.0,1);
x、 put(4.1,2);
//..并将以下内容放入循环中
y=x.get(2.0);//y=1
但是在HashMap
中使用Double作为key
是可以做到的,但是这可能不是一个好主意,因为Double
比较可能有浮点问题。但是基本思想是使用O(1)成本。你为什么要从问题中删除代码?怎么做?你能详细解释一下吗?@progy\u rock,这是编辑问题格式时的一个打字错误。它已被更正。你是在追求代码的简单性还是效率?我主要是在追求效率。代码的简单性可能是另一个可取的品质。这是O(n^2),绝对不会比最初的方法快。在大小小于~7000的阵列上,速度更快。此解决方案可行,但似乎比我的解决方案更复杂。
Map<Double,Integer> x = new HashMap<Double, Integer>();
x.put(3.5,0);
x.put(2.0,1);
x.put(4.1,2);
//.... and put following in loop
y=x.get(2.0); //y=1