Java:排序索引数组

时间:2013-01-06 20:41:59

标签: java arrays sorting indexing

快速提问:我有一个数组double[]array=new double [10],其中有随机双打,比如0到20之间。 我想要的是获得另一个数组int []resultingArray=new int [array.length],每个值int是array[]的值的两倍索引,从最大数字到最小数量排序。 因为我的英文很糟糕,这是一个“图表”:

array =(2,6,3) _ __ _ _ resulArray =(1,2,0)

这是一个考试问题。双打是来自学生的GPA,它要求一个方法返回一个由ID(在我的代码中是double []数组的索引)组成的数组,从最好的学生到最差的学生。

6 个答案:

答案 0 :(得分:1)

有很多使用Map的解决方案,我会建议只使用数组的替代方案:

public int[] getIndices(double[] originalArray)
{
    int len = originalArray.length;

    double[] sortedCopy = originalArray.clone();
    int[] indices = new int[len];

    // Sort the copy
    Arrays.sort(sortedCopy);

    // Go through the original array: for the same index, fill the position where the
    // corresponding number is in the sorted array in the indices array
    for (int index = 0; index < len; index++)
        indices[index] = Arrays.binarySearch(sortedCopy, originalArray[index]);

    return indices;
}
然而,这是非常低效的。

答案 1 :(得分:0)

如果学生的scaore是随机的,你可以做到这一点(这在现实世界中没有多大意义,因为你不能/不能给学生打分完全 15位数的准确度;)< / p>

public static int[] sortWithIndex(double[] results) {
    class ScoreIndex implements Comparable<ScoreIndex> {
        final double score;
        final int index;

        ScoreIndex(double score, int index) {
            this.score = score;
            this.index = index;
        }

        @Override
        public int compareTo(ScoreIndex o) {
            int cmp = Double.compare(score, o.score);
            return cmp == 0 ? Integer.compare(index, o.index) : cmp;
        }
    }
    List<ScoreIndex> list = new ArrayList<>();
    for (int i = 0; i < results.length; i++) list.add(new ScoreIndex(results[i], i));
    Collections.sort(list);
    int[] indexes = new int[results.length];
    for (int i = 0; i < list.size(); i++) indexes[i] = list.get(i).index;
    return indexes;
}

如果你对学生进行评分以限制精确度,那么只说&lt;你可以做6位数

public static void sortWithIndex(double[] results) {
    for(int i = 0; i < results.length; i++)
        results[i] = results[i] * results.length * 1e6 + i;
    Arrays.sort(results);
}

results现在按值的顺序包含所有原始值及其来自的索引,如果存在重复,则首先包含较低的索引。

答案 2 :(得分:0)

可能是这样的:

import java.util.*;

public class Test
{
    static Integer[] getIndicesInOrder(Integer[] array)
    {
        Integer[] c = array.clone();
        Arrays.sort(c, Collections.reverseOrder());

        List<Integer> l = Arrays.asList(array);

        for (int i = 0; i < array.length; ++i)
        {
            c[i] = l.indexOf(c[i]);
        }

        return c;
    }

    public static void main(String[] args)
    {
        Integer[] array = {2,6,3};

        System.out.println(Arrays.toString(getIndicesInOrder(array)));
    }
}

答案 3 :(得分:0)

我将如何做到这一点:

  • array的所有元素放在Map<Integer, Double>中,将索引映射到值。

  • 将此地图的entrySet()的所有元素放入列表中,并按值对该列表进行排序。

  • 从新排序的条目列表的键中形成一个数组。


public static int[] getIndicesInOrder(double[] array) {
    Map<Integer, Double> map = new HashMap<Integer, Double>(array.length);
    for (int i = 0; i < array.length; i++)
        map.put(i, array[i]);

    List<Entry<Integer, Double>> l = 
                           new ArrayList<Entry<Integer, Double>>(map.entrySet());

    Collections.sort(l, new Comparator<Entry<?, Double>>() {
            @Override
            public int compare(Entry<?, Double> e1, Entry<?, Double> e2) {
                return e2.getValue().compareTo(e1.getValue());
            }
        });

    int[] result = new int[array.length];
    for (int i = 0; i < result.length; i++)
        result[i] = l.get(i).getKey();

    return result;
}

public static void main(String[] args) {
    double[] array = { 1.1, 2.2, 3.3, 4.4, 3.3 };

    System.out.println(Arrays.toString(getIndicesInOrder(array)));
}
[3, 2, 4, 1, 0]

答案 4 :(得分:0)

  

这是一个考试问题。双打是来自学生的GPA,它要求   对于一个返回由ID组成的数组的方法(在我的   代码是double [] array的索引,来自最好的学生   学生最坏的。

我会用Map来做。 <ID, Doubles>。我们不能直接使用TreeMap,因为它按Key排序。我们想按价值排序(那些双打)。然而,我们可以做一些技巧来制作我们自己的比较器。按值排序地图。

我是在junit测试类中写的,

@Test
public void testArray() {
    final double[] array = new double[] { 1.1, 2.2, 3.3, 4.4, 3.3 };
    final int[] result = new int[array.length];

    final Map<Integer, Double> map = new HashMap<Integer, Double>();
    for (int i = 0; i < array.length; i++) {
        map.put(i, array[i]);
    }
    final List<Map.Entry> list = new LinkedList<Map.Entry>(map.entrySet());
    Collections.sort(list, new Comparator() {
        @Override
        public int compare(final Object o1, final Object o2) {
            return 0 - ((Comparable) ((Map.Entry) o1).getValue()).compareTo(((Map.Entry) o2).getValue());
        }
    });
    for (int i = 0; i < list.size(); i++) {

        result[i] = (Integer) list.get(i).getKey();
    } 

    //here we have result, to test it:
    for (final int element : result) {
        System.out.println(element);
    }
}

打印:

    3
    2
    4
    1
    0

答案 5 :(得分:0)

您可以使用自定义Comparator比较各个索引的成绩数组中的值

import java.util.*;

public class GradeComparator implements Comparator<Integer> {
    private double[] grades;
    public GradeComparator(double[] arr) {
        grades = arr;
    }
    public int compare(Integer i, Integer j) {
        return Double.compare(grades[j], grades[i]);
    }
}

使用Comaprator

对索引数组进行排序

import java.util。*;

public class SortGrades {
    public static void main(String[] args) {
        double[] grades = { 2.4, 6.1, 3.9, 4.8, 5.5 };
        Integer[] ranks = new Integer[grades.length];
        for(int i = 0; i < ranks.length; ++i) {
            ranks[i] = i;
        }
        Comparator<Integer> gc = new GradeComparator(grades);
        Arrays.sort(ranks, gc);
        for(int i = 0; i < ranks.length; ++i) {
            System.out.println((i+1) + ": " + ranks[i] + ", grade: " + grades[ranks[i]]);
        }
    }
}

输出

1: 1, grade: 6.1
2: 4, grade: 5.5
3: 3, grade: 4.8
4: 2, grade: 3.9
5: 0, grade: 2.4

根据需要。