8

我需要从数组中选择 10 个最小的数字(包含 2 000 个项目)并打印它们的索引。

起初我尝试对这个数组进行排序并打印值数组 [0 到 9]。这是最小的数字,但我丢失了这些值的索引,它们有一个未排序的数组。

第二个选项尝试使用效果很好的treeMap,但是当我有两个相等的键时,它只打印其中一个,但我需要同时打印它们。

使用 treeMap 的代码示例:

  TreeMap<Integer, String> treemap = new TreeMap<Integer, String>();

  treemap.put(2, "two");
  treemap.put(1, "one");
  treemap.put(3, "three");
  treemap.put(6, "six");
  treemap.put(6, "six2");
  treemap.put(5, "five");      

  Collection<String> coll=treemap.values();
  System.out.println("Value of the collection: "+coll);  

直到现在我不使用treeMap,所以有可能存在一些简单的方法来解决它。还是更好地使用其他东西?

我将不胜感激任何帮助

4

5 回答 5

4

这是最小的数字,但我丢失了这些值的索引,它们有我未排序的数组

那你为什么不创建一个类来保存这个索引呢?然后只需按值对数组进行排序,您将获得关联的索引。

class MyClass implements Comparable<MyClass>{
    private int index;
    private int value;

    public MyClass(int i, int v){
       this.index = i;
       this.value = v;
    }

    @Override
    public String toString(){
        return "Index: "+index+" Value: "+value;
    }

    @Override
    public int compareTo(MyClass m) {
        return value - m.value;
    }
}

public static void main(String[] args){   
    MyClass[] array = new MyClass[20];

    for(int i = 0; i < array.length; i++){
       array[i] = new MyClass(i, someRandomValue); // Here I used (i*3 + 2)%5
    }
    System.out.println(Arrays.toString(array));
    Arrays.sort(array);
    MyClass [] arraySorted = Arrays.copyOfRange(array, 0, 10); //take the first ten elements
    System.out.println(Arrays.toString(arraySorted));
}


笔记 :

如果要按索引对具有相同值的对象进行排序,可以像这样修改比较器:

@Override
public int compareTo(MyClass m) {
    int compareValue = value - m.value;
    if(compareValue == 0)
        return index - m.index;
    return compareValue;
}


输出(使用第二种compareTo方法):

Before :
[Index: 0 Value: 2, Index: 1 Value: 0, Index: 2 Value: 3, Index: 3 Value: 1, Index: 4 Value: 4, Index: 5 Value: 2, Index: 6 Value: 0, Index: 7 Value: 3, Index: 8 Value: 1, Index: 9 Value: 4, Index: 10 Value: 2, Index: 11 Value: 0, Index: 12 Value: 3, Index: 13 Value: 1, Index: 14 Value: 4]

After :
[Index: 1 Value: 0, Index: 6 Value: 0, Index: 11 Value: 0, Index: 3 Value: 1, Index: 8 Value: 1, Index: 13 Value: 1, Index: 0 Value: 2, Index: 5 Value: 2, Index: 10 Value: 2, Index: 2 Value: 3]
于 2013-11-02T14:51:52.907 回答
2

不是对裸值进行排序(value, index),而是对对进行排序value。然后,您只需取前 10 对,就有 10 个原始索引。

例如,您要排序:

6 2 7 4

配对(value, index)

(6, 0) (2, 1) (7, 2) (4, 3) 

关于排序value

(2, 1) (4, 3) (6, 0) (7, 2) 

指数:

1 3 0 2

你的方法TreeMap很好。您必须进行的唯一修改如下所示:

class Pair implements Comparable<Pair> {
    int value;
    int index;

    @Override
    int compareTo(Pair other) { return value - other.value };
}

Map<Pair, String> map = new TreeMap<Pair, String>();
于 2013-11-02T14:53:18.140 回答
1

创建一个简单的类来保存两个整数,或者对任何值使用泛型:

class Item<T> { 
    public int index;
    public T value;
    public Item(int index, T value) {
        this.index = index;
        this.value = value;
    }
}

并利用Collections.sort.

double[] original = { 1.0, 7.0, 3.0, -1.0, 5.0 };

List<Item> l = new ArrayList<Item<Double>>();
for (int i = 0; i < original.length; i++)
    l.add(new Item<Double>(i, original[i]));

Collections.sort(l, new Comparator<Item<Double>>() {
    public int compare(Item o1, Item o2) {
        return Double.compare(o1.value, o2.value);
    }
});

for (int i = 0; i < 10 && i < l.size(); i++) {
    System.out.printf("index: %f, value: %f%n", 
              l.get(i).index, l.get(i).value);
}

输出:

index: 3, value: -1
index: 0, value: 1
index: 2, value: 3
index: 4, value: 5
index: 1, value: 7
于 2013-11-02T15:06:50.297 回答
0

您可以通过稍微修改的快速排序来做到这一点,同时如果您交换索引数组,那么对数组进行排序也可以做到这一点

public class Quicksort 
{
    private int[] numbers;
    private int number;

    public void sort(int[] values) {
        if (values ==null || values.length==0){
           return;
        }
        this.numbers = values;
        number = values.length;
        quicksort(0, number - 1);
    }

    private void quicksort(int low, int high) {
        int i = low, j = high;
        int pivot = numbers[low + (high-low)/2];

        while (i <= j) {
            while (numbers[i] < pivot) {
                i++;
            }
            while (numbers[j] > pivot) {
               j--;
            }

            if (i <= j) {
                exchange(i, j);
                i++;
                j--;
            }
        }

        if (low < j)
            quicksort(low, j);
        if (i < high)
            quicksort(i, high);
    }

这是我们做出改变的地方

    private void exchange(int i, int j) {
    int temp = numbers[i];
    numbers[i] = numbers[j];
    numbers[j] = temp;

    // NOTICE THIS exchange the indexes as well
    temp = index_numbers[i];
    index_numbers[i] = index_numbers[j];
    index_numbers[j] = temp;
    }
}
于 2013-11-02T14:57:47.030 回答
0

简短的解决方案:

  1. 创建索引数组(用于初始化的简单 for 循环)。

  2. 使用自定义比较函数对该索引数组进行排序,该函数比较另一个数组中索引的值。注意:如果要按顺序打印索引,请使用稳定排序。

  3. 迭代排序的索引数组,打印索引并计算不同的值(当值改变时增加计数器),当计数器变为 11 时停止。

于 2013-11-02T15:04:55.473 回答