搜索排序列表<long>表示最近且小于</long>

时间:2013-10-05 13:56:04

标签: java list search arraylist match

考虑一些名为long的{​​{1}}和一个已排序的X。在List<Long>中找到(i)小于List<Long>(ii)的索引或值的最有效算法是什么?在数字线上最接近X(假设条件(i)已被饱和)?

例如,这可能是一个问题设置:

X

我希望算法返回long X = 500; List<Long> foo = new Arraylist<Long>(); foo.add(450L); foo.add(451L); foo.add(499L); foo.add(501L); foo.add(550L); Collections.sort(foo); // It's always sorted. 或返回与499相关联的索引(在本例中为499)。

3 个答案:

答案 0 :(得分:16)

鉴于列表中的值是唯一的,我建议您使用Set,更具体地说是TreeSet,因为您无论如何都要对列表进行排序。您可以使用完全符合要求的NavigableSet#floor(E)方法。

  

返回此集合中小于或等于给定元素的最大元素,如果没有这样的元素,则返回null

所以,代码看起来像:

long X = 500;
NavigableSet<Long> foo = new TreeSet<Long>();

foo.add(450L);
foo.add(451L);    
foo.add(499L);
foo.add(501L);
foo.add(550L);

System.out.println(foo.floor(X));   // 499

该方法也适用于用户定义的对象。只需在实例化时将Comparator<YourClass>传递给TreeSet构造函数。

答案 1 :(得分:6)

/ *在列表中找到最近的号码  * @param整数列表  * @param num到最接近的数字  * @return最近的号码  * * /

public static int findClosestNumber(List list, int num) {
    if (list.size() > 0) { // Check list does not empty
        int smaller =
            (Integer)Collections.min(list); // get min number from the list
        int larger =
            (Integer)Collections.max(list); // get max number from the list

        for (int i = 0; i < list.size(); i++) { //Traverse list
            if (num == (Integer)list.get(i))   //if find the passed number in the list
                return num;                     //than return num
            if (num > (Integer)list.get(i) && smaller < (Integer)list.get(i)) // find nearest smaller
                smaller = (Integer)list.get(i);
            if (num < (Integer)list.get(i) && larger > (Integer)list.get(i)) // find nearest larger
                larger = (Integer)list.get(i);
        }
        return (num - smaller < larger - num ? smaller : larger); // return closest number
    }
return 0;
}

}

答案 2 :(得分:5)

您可以使用java的Collections.binarySearch,因为您的列表已经过排序。

the spec中,二进制搜索返回:

  

搜索键的索引(如果它包含在列表中);   否则,( - (插入点) - 1)。插入点定义为   键将插入列表的位置:索引   第一个元素大于键,或list.size()如果全部   列表中的元素小于指定的键。请注意这一点   当且仅当密钥时,保证返回值>&gt; = 0   找到了。

首先,如果你进行二元搜索并且元素在列表中,你将获得一个正值(元素的索引),并且可以返回它(或者如果你仍然想要一个你可以少的元素从那里向后走,直到找到一个。)

否则,如果搜索列表中没有的内容,则可以从返回值向后返回所需的索引。如果在示例列表中搜索500,则算法将返回(-3 - 1)= -4。因此,您可以添加1以返回到插入点(-3),然后乘以-1并减去1以获得索引BEFORE第一个元素GREATER而不是您搜索的元素,这将是一个索引如果列表中的所有元素都大于您搜索的元素,则符合您的2个条件或-1。

在树集上使用二进制搜索的优点是它可能会减少开销。