二元搜索对列表

时间:2017-02-05 17:48:19

标签: java arraylist binary-search

我需要找到与 myptr(make_shared<Example<T>>(/*arguments*/)) 匹配的elem 我的程序有效,但效率不高。我有一个非常大的element(超过4000个元素),我使用二进制搜索来查找匹配的索引。

ArrayList<Obj> pairs

我想知道是否有一种比使用循环将一半ArrayList对复制到新的ArrayList列表更有效的方法。 Obj的构造函数:public int search(String element) { ArrayList<String> list = new ArrayList<String>(); for (int i = 0; i < pairs.size(); i++) { list.add(pairs.get(i).getElem()); } return index = Collections.binarySearch(list, element); }

2 个答案:

答案 0 :(得分:0)

如果您的主列表(pairs)没有更改,那么我建议您创建TreeMap以维持反向index结构,例如:

List<String> pairs = new ArrayList<String>(); //list containing 4000 entries

Map<String, Integer> indexMap = new TreeMap<>();

int index = 0;
for(String element : pairs){
    indexMap.put(element, index++);
}

现在,在搜索元素时,您需要做的只是:

indexMap.get(element);

如果元素不存在,那将为您提供所需的indexnull。此外,如果元素可以多次出现在列表中,则可以将indexMap更改为Map<String, List<Integer>>

您当前的算法会迭代列表并调用二进制搜索,因此迭代和O(n)的复杂度为O(log n),而TreeMap保证log(n)时间成本,因此它将是更快。

HereTreeMap的文档。

答案 1 :(得分:0)

看起来问题已经解决了。 由于我的问题是ArrayList对类型是bus_cif.y4mObj类型是String,我无法使用Collections.binarySearch,我决定创建一个新变量 element。看起来字符串不会导致任何问题(它通过了我的JUnit测试),因为我的Obj x = new Obj(element, "");方法比较了两个compareTo并忽略了elem的第二个变量。

我的更新方法:

Obj x