Java 搜索已排序列表<;长期>;最接近且小于
考虑一些名为Java 搜索已排序列表<;长期>;最接近且小于,java,list,search,arraylist,match,Java,List,Search,Arraylist,Match,考虑一些名为X的long和一个排序的列表。在列表中查找(i)小于X,且(ii)最接近编号行上X的索引或值的最有效算法是什么(假设条件(i)已满足) 例如,这可能是一个问题设置: 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.sor
X
的long
和一个排序的列表
。在列表中查找(i)小于X
,且(ii)最接近编号行上X
的索引或值的最有效算法是什么(假设条件(i)已满足)
例如,这可能是一个问题设置:
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.
长X=500;
List foo=new Arraylist();
添加食物(450L);
食品添加剂(451L);
foo.add(499L);
foo.add(501L);
食品添加剂(550L);
集合。排序(foo);//它总是分类的。
我希望算法返回499
或返回与499
相关联的索引(在本例中为I=2
) 鉴于列表中的值是唯一的,我建议您使用集,更具体地说是a,因为您正在对列表进行排序。你可以使用你想要的方法
返回此集合中小于或等于给定元素的最大元素,如果没有此类元素,则返回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
长X=500;
NavigableSet foo=新树集();
添加食物(450L);
食品添加剂(451L);
foo.add(499L);
foo.add(501L);
食品添加剂(550L);
系统输出打印LN(楼层(X));//499
该方法也适用于用户定义的对象。只需在实例化时将比较器
传递给树集
构造函数。您可以使用java的集合。binarySearch
进行此操作,因为您的列表已排序
在中,二进制搜索返回:
搜索键的索引(如果它包含在列表中);
否则,((插入点)-1)。插入点定义为
将键插入列表的点:索引
大于键的第一个元素的值,或list.size()如果全部
列表中的元素小于指定的键。请注意
保证当且仅当
找到了
首先,如果您进行二进制搜索,并且元素在列表中,您将得到一个正值(元素的索引),并且可以返回该值(或者如果您仍然需要一个较小的元素,您可以从那里向后走,直到找到一个为止)
否则,如果搜索不在列表中的内容,可以从返回值向后搜索到所需的索引。如果在示例列表中搜索500,算法将返回(-3-1)=-4。因此,您可以加1回到插入点(-3),然后乘以-1减去1,得到第一个元素之前的索引大于您搜索的元素,该索引将满足您的2个条件,或者如果列表中的所有元素都大于您搜索的元素,则为-1
与树集相比,使用二进制搜索的优点是,它可能具有较少的开销。/*在列表中查找最接近的数字
*@param整数列表
*@param num找到最接近的数字
*@返回最近的号码
**/
public static int findClosestNumber(列表,int num){
如果(list.size()>0){//检查列表不为空
整数更小=
(整数)Collections.min(list);//从列表中获取最小编号
整数较大=
(整数)Collections.max(list);//从列表中获取max number
对于(inti=0;i(Integer)list.get(i)和&small<(Integer)list.get(i))//查找最近的较小值
较小=(整数)list.get(i);
if(num<(Integer)list.get(i)和&larger>(Integer)list.get(i))//查找最近的较大值
较大=(整数)list.get(i);
}
return(num-smaller
}列表中的值是唯一的吗?@RohitJain是的,关于boo boo很抱歉,列表是否始终排序?@Jeroenvanevel是的,列表始终使用集合进行排序。排序()
请查看此链接以查找列表中最接近的值。。我的foo
是否必须在NavigableSet
中排序?@user2763361它们将自动排序,因为您在此处使用的是TreeSet
。它根据元素的自然顺序或创建元素时使用的任何比较器对元素进行排序。当我的列表包含重复值(但仍然可以排序)时,是否有类似的对象?对于重复值,这将不起作用。该方法仅适用于Set
。您可以将列表转换为集合
,使用此方法查找最接近的匹配项,然后从列表中获取所有匹配项。这当然需要您创建一个额外的Set
对象。如何将名为foo
的列表
键入树集
?我只是把它放到构造函数中吗?
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;
}