Algorithm 如何在查找表中搜索最接近的值?

Algorithm 如何在查找表中搜索最接近的值?,algorithm,search,Algorithm,Search,我有一个简单的一维整数值数组,它表示我必须处理的一组物理部分值。然后我用数学方法计算理想值 我怎样才能编写一个高效的搜索算法,找到数组中与理想值的最小结果差 数组是预先确定的,并且是常量,因此可以根据需要对其进行排序 范例 查找数组: 100, 152, 256, 282, 300 搜索理想值125会在数组中找到100,而127会找到152 实际查找数组的长度约为250个项目,并且永远不会更改。只需遍历数组并计算abs(reference-array_value[i])就需要O(N)。 携带差

我有一个简单的一维整数值数组,它表示我必须处理的一组物理部分值。然后我用数学方法计算理想值

我怎样才能编写一个高效的搜索算法,找到数组中与理想值的最小结果差

数组是预先确定的,并且是常量,因此可以根据需要对其进行排序

范例 查找数组:

100, 152, 256, 282, 300
搜索理想值125会在数组中找到100,而127会找到152


实际查找数组的长度约为250个项目,并且永远不会更改。

只需遍历数组并计算abs(reference-array_value[i])就需要O(N)。
携带差异最小的索引

数组排序后,使用Python,对未排序列表使用蛮力(因为编写Python很有趣)
O(n)

以及使用二进制搜索查找值
O(log\n)
的正确实现:

导入对分 ''将排序列表中最近的条目“排序”返回到“值” ''' def find_最接近(已排序,值): 如果(值=排序[-1]): 返回排序[-1] insertpos=bisect.bisect(已排序,值)
如果(abs(sorted[insertpos-1]-value)这与二进制搜索非常相似,除非它没有找到确切的密钥,否则它将返回一个密钥,该密钥与提供的密钥非常接近

逻辑是在执行二进制搜索时,搜索直到找到准确的键,或者直到在高键和低键之间只剩下一个键。

考虑一个数组n[]={1,2,4,6,8,10,12,14,16,18,20}
如果搜索关键字:2,则使用以下算法
步骤1:高=10,低=0,中等=5
步骤2:高=5,低=0,中等=2
步骤3:high=2,low=0,med=1在这一步中找到了确切的键。因此它返回1。

如果搜索键:3(数组中不存在),则使用以下算法
步骤1:高=10,低=0,中等=5
步骤2:高=5,低=0,中等=2
步骤3:高=2,低=0,中等=1
步骤4:high=1,low=0,在这一步high=low+1,即没有更多的元素要搜索。因此它返回med=1

希望这有助于

public static <T> int binarySearch(List<T> list, T key, Comparator<T> compare) {
                int low, high, med, c;
                T temp;
                high = list.size();
                low = 0;
                med = (high + low) / 2;

                while (high != low+1) {
                    temp = list.get(med);
                    c = compare.compare(temp, key);

                    if (c == 0) {
                        return med;
                    } else if (c < 0){
                        low = med;
                    }else{
                        high = med;
                    }

                    med = (high + low) / 2;
                }

                return med; 
            }

    /** ------------------------ Example -------------------- **/

    public static void main(String[] args) {
                List<Integer> nos = new ArrayList<Integer>();
                nos.addAll(Arrays.asList(new Integer[]{1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20}));

                search(nos, 2); // Output Search:2  Key:1   Value:2
                search(nos, 3); // Output Search:3  Key:1   Value:2

                search(nos, 10); // Output Search:10    Key:5   Value:10
                search(nos, 11); // Output Search:11    Key:5   Value:10
            }

    public static void search(List<Integer> nos, int search){
                int key = binarySearch(nos, search, new IntComparator());
                System.out.println("Search:"+search+"\tKey:"+key+"\tValue:"+nos.get(key));
            }

            public static class IntComparator implements Comparator<Integer>{
                @Override
                public int compare(Integer o1, Integer o2) {
                    return o1.compareTo(o2);
                }
            }
publicstaticintbinarysearch(列表、T键、比较器比较){
int低、高、中、c;
温度;
高=list.size();
低=0;
中等=(高+低)/2;
while(高!=低+1){
temp=列表获取(med);
c=比较。比较(温度、键);
如果(c==0){
返回医学院;
}else如果(c<0){
低=中等;
}否则{
高=中等;
}
中等=(高+低)/2;
}
返回医学院;
}
/**---------------------------示例------------------**/
公共静态void main(字符串[]args){
列表编号=新的ArrayList();
nos.addAll(Arrays.asList(新整数[]{1,2,4,6,8,10,12,14,16,18,20}));
搜索(nos,2);//输出搜索:2键:1值:2
搜索(nos,3);//输出搜索:3键:1值:2
搜索(nos,10);//输出搜索:10键:5值:10
搜索(nos,11);//输出搜索:11键:5值:10
}
公共静态无效搜索(列表编号,整数搜索){
int key=binarySearch(nos,search,newintcomparator());
System.out.println(“搜索:“+Search+”\tKey:“+key+”\tValue:“+nos.get(key));
}
公共静态类IntComparator实现Comparator{
@凌驾
公共整数比较(整数o1,整数o2){
返回o1。与(o2)相比;
}
}

维基百科的二进制搜索算法如下:

int binary_search(int A[], int key, int imin, int imax)
{
  // continue searching while [imin,imax] is not empty
  while (imax >= imin)
    {
      // calculate the midpoint for roughly equal partition
      int imid = midpoint(imin, imax);
      if(A[imid] == key)
        // key found at index imid
        return imid; 
      // determine which subarray to search
      else if (A[imid] < key)
        // change min index to search upper subarray
        imin = imid + 1;
      else         
        // change max index to search lower subarray
        imax = imid - 1;
    }
  // key was not found
  return KEY_NOT_FOUND;
}

但这是否总是能找到最接近的匹配项?我只见过精确匹配的实现。如果没有精确匹配项,您可以将其设置为给出前一个或后一个。然后您只需检查两个值,看看哪个值最接近。@CSharperWithJava,您可以使用博客文章中的示例,使用二进制搜索查找最接近的项:I agr带OP注释的ee。普通二进制搜索不会返回最接近的匹配项,并且根本不清楚为了返回该匹配项,算法将进行哪些更改。@rghome-是否存在重复值?您知道值的范围吗(即,1public static <T> int binarySearch(List<T> list, T key, Comparator<T> compare) { int low, high, med, c; T temp; high = list.size(); low = 0; med = (high + low) / 2; while (high != low+1) { temp = list.get(med); c = compare.compare(temp, key); if (c == 0) { return med; } else if (c < 0){ low = med; }else{ high = med; } med = (high + low) / 2; } return med; } /** ------------------------ Example -------------------- **/ public static void main(String[] args) { List<Integer> nos = new ArrayList<Integer>(); nos.addAll(Arrays.asList(new Integer[]{1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20})); search(nos, 2); // Output Search:2 Key:1 Value:2 search(nos, 3); // Output Search:3 Key:1 Value:2 search(nos, 10); // Output Search:10 Key:5 Value:10 search(nos, 11); // Output Search:11 Key:5 Value:10 } public static void search(List<Integer> nos, int search){ int key = binarySearch(nos, search, new IntComparator()); System.out.println("Search:"+search+"\tKey:"+key+"\tValue:"+nos.get(key)); } public static class IntComparator implements Comparator<Integer>{ @Override public int compare(Integer o1, Integer o2) { return o1.compareTo(o2); } }
int binary_search(int A[], int key, int imin, int imax)
{
  // continue searching while [imin,imax] is not empty
  while (imax >= imin)
    {
      // calculate the midpoint for roughly equal partition
      int imid = midpoint(imin, imax);
      if(A[imid] == key)
        // key found at index imid
        return imid; 
      // determine which subarray to search
      else if (A[imid] < key)
        // change min index to search upper subarray
        imin = imid + 1;
      else         
        // change max index to search lower subarray
        imax = imid - 1;
    }
  // key was not found
  return KEY_NOT_FOUND;
}
if imax <= 0 return 0
if imin >= A.count - 1 return A.count - 1
if (key - A[imax]) < (A[imin] - key) return imax
return imin