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-是否存在重复值?您知道值的范围吗(即,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);
}
}
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