如果你需要多次搜索(同一个数组),你可能会创建一个临时结构,它结合了原始索引和值:
class Pair implements Comparable<Pair> {
final int index;
final int value;
Pair(int index, int value) {
this.index = index;
this.value = value;
}
public int compareTo(Pair oth) {
if (value < oth.value) return -1;
else if (value > oth.value) return 1;
else if (index < oth.index) return -1;
else if (index > oth.index) return 1;
else return 0;
}
}
final ArrayList<Pair> list = new ArrayList<Pair>();
for (int k = 0; k < array.length; ++k) {
list.add(new Pair(k, array[k]);
}
Arrays.sort(list);
现在,list 按值排序,然后按索引排序。我们现在可以使用二分搜索(例如)来查找元素。但是请注意,这仅是值得的,如果您搜索值的次数(现在是 O(log n) 而不是 O(n))支配了构建数组所需的时间((O(n log n) 由于排序)。
或者,您可以使用HashMap 或TreeMap 构建一个类似索引的结构,它将整数值映射到它在数组中的位置。在使用HashMap 的情况下,访问时间将在O(1) 左右,在TreeMap 的情况下,访问时间将是O(log n),与上面提出的二进制搜索方法一样。
如果您必须经常搜索数组,所有这些建议显然是值得的。
此外,您应该考虑,如果数组相当小,使用简单的线性搜索(如其他人所建议的那样)实际上可能是最快的解决方案,因为所涉及的“常量”和数组组件的良好局部性.
因此,另一种方法是在将Pair 结构排序为两个整数数组(一个包含值,另一个包含索引)之后再次解包:
int[] values = new int[list.size()];
int[] indices = new int[list.size()];
int pt = 0;
for (Pair p: list) {
values[pt] = p.value;
indices[pt] = p.index;
pt += 1;
}
现在您可以使用二进制搜索来搜索values 数组:
int position = Arrays.binarySearch(values, valueToLookFor);
if (position >= 0) {
// Found it!
int index = indices[position];
System.out.println("Value was originally stored in " + index);
} else {
// Value not found
}
请记住:最简单的解决方案(线性扫描)可能是最快的,具体取决于数组的大小和您需要搜索条目的次数。我实际上会先尝试一下,并且只使用其中一个更复杂的建议,如果它被证明是一个瓶颈。