【问题标题】:Find greater than X from list when X doesn't exist in list当列表中不存在 X 时,从列表中查找大于 X
【发布时间】:2013-11-03 23:17:13
【问题描述】:

我正在尝试从列表中查找大于某个值(在我的情况下已知)的值。

例子:

给定

list = [1, 2, 5, 10, 15];  //list is sorted

查找大于X(本例中为=7)的值。

期望的结果 = 返回一个包含值的列表 = [10, 15]

我试过用java二分搜索,比如

int index = Collections.binarySearch(list, X);

我的计划是找到索引(X),然后返回索引之后的所有元素。

但索引返回负数,我理解这是因为7 不在列表中。

还有其他方法吗?有人请建议。

【问题讨论】:

  • 其他方式:创建一个新列表并从原始列表中添加大于X的元素。
  • @RyanStewart,谢谢。

标签: java list binary-search


【解决方案1】:

从 Java 8 开始,您可以使用流。

import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
import java.util.stream.Collectors;

public class So1 {

   public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 5, 10, 15);
        List result = list.stream().filter(s -> s > 7).collect(Collectors.toList());
        System.out.println(result);
    }
}

对于这类数据计算,我强烈建议研究 Clojure,它可以编译为 Java。

例如,你会这样写:

(filter
    #(> % 7) 
    [1 2 5 10 15])

【讨论】:

  • 这家伙提出了一个问题,如何在 java 中而不是在 clojure 中做到这一点。也许他需要它来工作,因为他不能去他的老板请求允许开始用 Clojure 写作。
【解决方案2】:

如果您的列表排序超过Collection#binarySearch 将返回搜索键的索引,如果它包含在列表中;否则,(-(插入点)- 1)。您可以计算插入点的开始索引,如下所示:

     index= -(insertion_point) - 1
     -(insertion_point)= index+1
     insertion_point=-(index+1)

得到List的开始索引后,你可以应用subList方法得到大于X的结果列表。

    Integer[] values = {1, 2, 5, 10, 15};
    List<Integer> list = new ArrayList<>(Arrays.asList(values));
    int X = 7;
    int index = Collections.binarySearch(list, X);

    int insertion_point = -(index+1); // As calculated above.

    List<Integer> res = list.subList(insertion_point, list.size());
    System.out.println(res);

输出:[10, 15]

【讨论】:

    【解决方案3】:

    一种方法是使用传统的上、下和中点引用来实现您自己的二分搜索算法。通常,当在下面的方法中下端大于上端时,这意味着您要查找的数字不在列表中,但是在您的情况下,您可以将其用作列表中剩余项目的索引值的参考。

    public int find(int searchKey){
        int lowerBound = 0;
        int upperBound = nElems-1;
        int check;
    
        while(true){
           check = (lowerBound + upperBound ) / 2;
           if(myArray[check]==searchKey){
               return check; // found it
            }else if(lowerBound > upperBound){
                  //lowerbound is now the first index of the remaining values in the list.
                  // I think. You might want to test it...
    
            }else{ // divide range
                  if(myArray[check] < searchKey){
                     lowerBound = check + 1; // it's in upper half
                  }else{
                       upperBound = check - 1; // it's in lower half
               }
            } // end else divide range
          } // end while
       } // 
    

    【讨论】:

      【解决方案4】:
      List<Integer> list;
      List<Intger> out;
      
      int v = 7;
      for int i : list
          if i > v
              out.add(i)
      

      如果这是一个小列表,蛮力方法将起作用。

      您也可以使用 List 可用的一些方法,例如 subList -> List API

      for int i; i < list.size() ; i++
          if list.get(i) > 7
               return list.subList(i,list.size())
      return new List<Integer>() // return empty list
      

      【讨论】:

        【解决方案5】:

        Collections.binarySearch():

        返回:

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

        即使元素不在列表中,该方法仍会返回有意义的内容,而这正是您想要的。如果返回值r 为负数,则插入点为-(r + 1)。当然,如果r 是正数,那么元素包含在列表中的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-08-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-10-29
          • 1970-01-01
          相关资源
          最近更新 更多