查找数组中最接近的数字

时间:2009-02-06 10:58:20

标签: java

首先我们必须在数组中查找是否存在所需的数字? 如果没有,那么我如何在Java中找到给定所需数字的更近的数字?

11 个答案:

答案 0 :(得分:12)

一个想法:

int nearest = -1;
int bestDistanceFoundYet = Integer.MAX_INTEGER;
// We iterate on the array...
for (int i = 0; i < array.length; i++) {
  // if we found the desired number, we return it.
  if (array[i] == desiredNumber) {
    return array[i];
  } else {
    // else, we consider the difference between the desired number and the current number in the array.
    int d = Math.abs(desiredNumber - array[i]);
    if (d < bestDistanceFoundYet) {
      // For the moment, this value is the nearest to the desired number...
      bestDistanceFoundYet = d; // Assign new best distance...
      nearest = array[i];
    }
  }
}
return nearest;

答案 1 :(得分:3)

“更接近”的另一个常见定义是基于差异的平方。大纲类似于romaintaz提供的大纲,除了你计算

long d = ((long)desiredNumber - array[i]);

然后将(d * d)与最近距离进行比较。

注意 我已将d键入long而不是int以避免溢出,这可以即使使用基于绝对值的计算也会发生。(例如,考虑当desiredValue至少是最大32位有符号值的一半时会发生什么,并且数组包含一个具有相应值的值幅度但负面的迹象。)

最后,我编写了返回值所在位置索引的方法,而不是值本身。在这两种情况中的任何一种:

  • 当数组的长度为零时,
  • 如果你添加一个“容差”参数来限制你将被视为匹配的最大差异,

您可以使用-1作为类似于indexOf上的规范的带外值。

答案 2 :(得分:2)

//这将有效

public int nearest(int of, List<Integer> in)
{
int min = Integer.MAX_VALUE;
int closest = of;

for (int v : in) 
{
    final int diff = Math.abs(v - of);

    if (diff < min) 
    {
        min = diff;
        closest = v;
    }
}
return closest;
}

答案 3 :(得分:1)

如果数组已排序,则执行修改后的二进制搜索。基本上如果你没有找到数字,那么在搜索结束时返回下限。

答案 4 :(得分:1)

伪代码返回最接近整数的列表。

myList = new ArrayList();          

if(array.length==0) return myList; 

myList.add(array[0]);

int closestDifference = abs(array[0]-numberToFind);

for (int i = 1; i < array.length; i++) {

 int currentDifference= abs(array[i]-numberToFind);

  if (currentDifference < closestDifference) {

    myList.clear();

    myList.add(array[i]);

         closestDifference = currentDifference;

  } else {

    if(currentDifference==closestDifference) {

        if( myList.get(0) !=array[i]) && (myList.size() < 2) {

            myList.add(array[i]);

        }
            }

       }

}

return myList;

答案 5 :(得分:0)

Array.indexOf()找出是否存在wheter元素。如果没有,则迭代一个数组并维护一个变量,该变量保存所需元素和i元素之间的差值的绝对值。返回绝对差异最小的元素。

总体复杂度为 O(2n),可以进一步减少为数组上的单次迭代(即 O(n))。虽然不会有太大的不同。

答案 6 :(得分:0)

唯一缺少的是更接近的语义。

如果你正在寻找六个,你的阵列有四个和八个,你会怎么做?

哪一个最接近?

答案 7 :(得分:0)

   int d = Math.abs(desiredNumber - array[i]);
    if (d < bestDistanceFoundYet) {
      // For the moment, this value is the nearest to the desired number...
      nearest = array[i];
    }

通过这种方式,您可以找到最接近所需数字的最后一个数字,因为 bestDistanceFoundYet 是常量而 d 会记住最后一个值,如果(d <... 。)

如果您希望找到距离所需数字更近的数字( d 无关紧要),您可以记住最后一个可能值。 如果你可以测试

if(d<last_d_memorized){ //the actual distance is shorter than the previous
    // For the moment, this value is the nearest to the desired number...
          nearest = array[i];
    d_last_memorized=d;//is the actual shortest found delta 
}

答案 8 :(得分:0)

要指出的一些事项:

1 - 您可以使用

将数组转换为列表
Arrays.asList(yourIntegerArray);

2 - 使用列表,您只需使用indexOf()。

3 - 考虑一个场景,你有一个长度的列表,你想要最接近3的数字,你已经发现2在数组中,你知道3不是。如果不检查其他数字,你可以得出结论,2是最好的,因为它不可能更接近。我不确定indexOf()是如何工作的,所以这可能实际上并没有加快你的速度。

4 - 扩展3,假设indexOf()不会花费更多时间来获取索引处的值。然后,如果你想要一个数组中最接近3的数字并且你已经找到了1,并且还有更多的数字需要检查,那么检查数组中的2或4是否会更快。

5 - 在3和4上扩展,我认为可以将它应用于浮点数和双精度数,尽管它需要使用小于1的步长...计算有多小似乎超出范围但问题是。

答案 9 :(得分:0)

// paulmurray's answer to your question is really the best :

// The least square solution is way more elegant, 
// here is a test code where numbertoLookFor
// is zero, if you want to try ...

import java.util.* ;

public class main {
    public static void main(String[] args) 
    {
        int[] somenumbers = {-2,3,6,1,5,5,-1} ;
        ArrayList<Integer> l = new ArrayList<Integer>(10) ;
        for(int i=0 ; i<somenumbers.length ; i++)
        {
            l.add(somenumbers[i]) ;
        }
        Collections.sort(l, 
                new java.util.Comparator<Integer>()
                {
                    public int compare(Integer n1, Integer n2)
                    {
                        return n1*n1 - n2*n2 ;
                    }
                }
        ) ;
        Integer first = l.get(0) ;
        System.out.println("nearest number is " + first) ;  
    }
}

答案 10 :(得分:-1)

int[] somenumbers = getAnArrayOfSomenumbers();
int numbertoLookFor = getTheNumberToLookFor();

boolean arrayContainsNumber = 
   new HashSet(Arrays.asList(somenumbers))
      .contains(numbertoLookfor);

它也很快。

哦 - 你想找到最近的号码?在那种情况下:

int[] somenumbers = getAnArrayOfSomenumbers();
int numbertoLookFor = getTheNumberToLookFor();

ArrayList<Integer> l = new ArrayList<Integer>(
  Arrays.asList(somenumbers)
);
Collections.sort(l);
while(l.size()>1) {
  if(numbertoolookfor <= l.get((l.size()/2)-1)) {
    l = l.subList(0, l.size()/2);
  }
  else {
    l = l.subList(l.size()/2, l.size); 
  }
}

System.out.println("nearest number is" + l.get(0));

哦 - 坚持:你是在追求最小二乘解决方案?

Collections.sort(l,  new Comparator<Integer>(){
  public int compare(Integer o1, Integer o2) {
    return (o1-numbertoLookFor)*(o1-numbertoLookFor) - 
           (o2-numbertoLookFor)*(o2-numbertoLookFor);
  }});

System.out.println("nearest number is" + l.get(0));