我有一个填充了Double值的ArrayList,并且根据用户输入(int),我需要从这个List中找到输入的最小双打数量的索引。例如,如果用户输入5,并且ArrayList看起来如此(实际上要大得多):
-6789.44658
-27239.73827
-12365.78370
-456.789457
-4768.42579
-15263.26399
-15263.26399
-0.0
-24688.7289
我会得到1, 5, 8, 2, 6
(从最小到最大的5个最小双打的顺序并不重要)。这是我到目前为止所做的:
int[] indices = new int[input];
List<Double> copy = new ArrayList<Double>(origList); //origList is list of Doubles
for (int t = 0; t < input; t++)
{
indices[t] = origList.indexOf(Collections.min(copy));
copy.remove(Collections.min(copy));
}
但是有两个问题:
感谢您的帮助!
答案 0 :(得分:1)
一种解决方案是使用您的origList并在使用值填充TreeMap<Double, List<Integer>>
后迭代它。密钥是你的double,列表是具有该值的索引列表。
TreeMap在向其添加项目时维护顺序,因此无需执行其他排序步骤。输入TreeMap是log(n)所以找时间最小的n个索引应该是O(log N)。
int input = 5;
List<Double> origList = new ArrayList<Double>();
origList.add(-6789.44658);
origList.add(-27239.73827);
origList.add(-12365.78370);
origList.add(-456.789457);
origList.add(-4768.42579);
origList.add(-15263.26399);
origList.add(-15263.26399);
origList.add(-0.0);
origList.add(-24688.7289);
TreeMap<Double, List<Integer>> smallest = new TreeMap<Double, List<Integer>>();
for (int i = 0; i < origList.size(); i++) {
double d = origList.get(i);
List<Integer> list = smallest.get(d);
if (list == null) {
list = new ArrayList<Integer>();
smallest.put(d, list);
}
list.add(i);
}
现在您已经将值的排序映射到它们的索引,您只需要从该映射中获取前n个键并获取它们的值,然后就完成了。
List<Integer> indices = new ArrayList<Integer>();
for (Double key : smallest.keySet()) {
List<Integer> list = smallest.get(key);
for (Integer index : list) {
indices.add(index);
if (indices.size() == input) break;
}
if (indices.size() == input) break;
}
System.out.println(smallest);
System.out.println(indices);
以上代码生成以下地图:
{-27239.73827=[1], -24688.7289=[8], -15263.26399=[5, 6], -12365.7837=[2], -6789.44658=[0], -4768.42579=[4], -456.789457=[3], -0.0=[7]}
以及以下最终输出:
[1, 8, 5, 6, 2]
答案 1 :(得分:0)
这样的事情怎么样?
public int[] getLowest(List<Double> list, int howMany) {
int[] indices = new int[howMany];
List<Double> copy = new ArrayList<>(list);
Collections.sort(copy);
List<Double> lowest = new ArrayList<>();
for (int i = 0; i < howMany; i++) {
lowest.add(copy.get(i));
}
int indicesIndex = 0;
for (int d = 0; d < list.size(); d++) {
if (lowest.contains(list.get(d))) {
indices[indicesIndex] = d;
indicesIndex++;
}
}
return indices;
}
答案 2 :(得分:0)
我遍历双列表,保留n个最小值并忽略重复。
这是结果。
[(-27239.73827, 1), (-24688.7289, 8), (-15263.26399, 5), (-12365.7837, 2),
(-6789.44658, 0)]
我意识到我归还了双打和指数。如果愿意,您可以从Minimum数组中获取索引。
此代码以O(n)运行。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class NSmallest implements Runnable {
private static final double LARGE_DOUBLE = 1.0E100;
private int n;
public static void main(String[] args) {
int n = 5;
new NSmallest(n).run();
}
public NSmallest(int n) {
this.n = n;
}
@Override
public void run() {
List<Double> numbers = loadList();
Minimum[] minimums = initializeMinimums();
for (int i = 0; i < numbers.size(); i++) {
double value = numbers.get(i);
minimums = getMinimum(minimums, value, i);
}
System.out.println(Arrays.toString(minimums));
}
private List<Double> loadList() {
List<Double> numbers = new ArrayList<>();
numbers.add(Double.valueOf(-6789.44658));
numbers.add(Double.valueOf(-27239.73827));
numbers.add(Double.valueOf(-12365.78370));
numbers.add(Double.valueOf(-456.789457));
numbers.add(Double.valueOf(-4768.42579));
numbers.add(Double.valueOf(-15263.26399));
numbers.add(Double.valueOf(-15263.26399));
numbers.add(Double.valueOf(-0.0));
numbers.add(Double.valueOf(-24688.7289));
return numbers;
}
private Minimum[] initializeMinimums() {
Minimum[] minimums = new Minimum[n];
for (int i = 0; i < minimums.length; i++) {
minimums[i] = new Minimum(LARGE_DOUBLE, -1);
}
return minimums;
}
private Minimum[] getMinimum(Minimum[] minimums, double value, int index) {
for (int i = 0; i < minimums.length; i++) {
double number = minimums[i].getNumber();
if (value == number) {
break;
} else if (value < number) {
int j = minimums.length - 2;
while (j >= i) {
minimums[j + 1].setIndex(minimums[j].getIndex());
minimums[j + 1].setNumber(minimums[j].getNumber());
j--;
}
minimums[i].setIndex(index);
minimums[i].setNumber(value);
break;
}
}
return minimums;
}
public class Minimum {
private double number;
private int index;
public Minimum(double number, int index) {
this.number = number;
this.index = index;
}
public double getNumber() {
return number;
}
public int getIndex() {
return index;
}
public void setNumber(double number) {
this.number = number;
}
public void setIndex(int index) {
this.index = index;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("(");
builder.append(number);
builder.append(", ");
builder.append(index);
builder.append(")");
return builder.toString();
}
}
}