Java中的内置比较排序

时间:2010-12-08 20:46:20

标签: java sorting comparison

假设我想对排序后随机选择的项目1到10进行排序,选择与每个数字的权重相关联的概率(即1的权重= 10,2 = 30,4 = 15,5 = 35,6 = = 10,其余0);假设我在此之前已经计算了权重之和。现在,我首先必须根据它们的权重对数字进行排序,然后再次通过列表将每个数字除以所有数字的总和(即规范化以使每个权重在[0,1]中)。排序然后遍历列表很慢,所以我尝试将权重放在compareTo()方法中,以便在排序时进行规范化,但如果我这样做,Collections.sort()不会将它们按正确顺序排列。任何建议(除了必须从头开始编写我自己的高效排序算法)?我希望我很清楚。

3 个答案:

答案 0 :(得分:1)

是什么让您认为您需要按重量排序以随机选择数字?

我会这样做:

int[] numbers;
int[] weight;

int totalweight;
for (int n : numbers) {
    totalweight += weight[n];
}

int t = new Random().nextInt(totalWeight);
for (int n : numbers) {
    t -= weight[n];
    if (t < 0) return n;
}

如果您从同一个数组中重复选择,您可能希望预先计算部分总和并对其进行二元搜索。

如果您的数组包含范围明显小于其长度的数字,您可以调整计数排序的想法,即为每个不同数字预先计算部分和,并对这些数字进行二元搜索。

很容易看出,除非您对所涉及的数字或权重有一些先验知识,否则您需要查看每个数字的权重(因为它可能使所有其他权重相形见绌),因此一般算法必须采用至少O(n)。

但是,其他约束允许更有效的实现。如果你知道一个数字的重量相当小的上限,你可以进行A / R采样:

int[] numbers;
int[] weight;
int maxWeight;

Random r = new Random();
do {
    c = numbers[r.nextInt(numbers.length)];
} while (r.nextInt(maxWeight) > weight[c]);
return c;

答案 1 :(得分:1)

假设intsList

Collections.sort(ints, new Comparator<Integer> () {
  private int getWeight(Integer i) {
    int weight = 0;
    switch(i) {
      case 1:
      case 6: weight = 10; break;
      case 2: weight = 30; break;
      case 4: weight = 15; break;
      case 5: weight = 35; break;
    }
    return weight;
  }

  public int compare(Integer i1, Integer i2) {
    int w1 = getWeight(i1);
    int w2 = getWeight(i2);
    return (w1>w2)?1:(w1==w2?0:-1);
  }});

for(int i:ints) {
  System.out.print(i+",");
}

您可以使用枚举或散列图来存储数字的权重,代码是如何进行基于权重的比较的示例。

答案 2 :(得分:0)

只是建议改进Meriton的优秀建议:

如果你想让第一部分更快,你可以创建一个索引,以便减少循环所需的元素。对于计算权重时的每个N数,记下数组/哈希中的索引和到目前为止的总和。

然后当您选择要循环的数字t时,您可以在索引中查找并跳转将元素传递到那里。如果您有大量条目和多次查找,可能会节省您的时间。