我正在阅读一本《数据 struct 和算法》一书,在关于数组内插搜索的章节中,这本书包括了这段代码:

def interpolation_search(ar:list, lo:int, hi:int, x:int):                                
    if (lo <= hi and x >= ar[lo] and x <= ar[hi]):                                       
        pos = lo + ((hi - lo) // (ar[hi] - ar[lo]) * (x - ar[lo]))                       
                                                                                           
        print(pos)                                                                       
                                                                                             
        if ar[pos] == x:                                                                 
            return pos                                                                   
                                                                                           
        if ar[pos] < x:                                                                  
            return interpolation_search(ar, pos + 1, hi, x)                              
                                                                                             
        if ar[pos] > x:                                                                  
            return interpolation_search(ar, lo, pos - 1, x)                              
                                                                                             
    return -1 
    
if __name__ == '__main__':                                                               
    v = 18                                                                                                                                                 
    ar = [10, 12, 13, 16, 18, 19, 20, 21, 22, 23, 24, 33, 35, 42, 47]                                                           
    assert(interpolation_search(ar, 0, len(ar)-1, v) == 4) 

现在我的问题是,如果我运行它,它将打印0、1、2、3、4(从打印(Pos)) 这看起来像是一个更复杂的线性搜索.

那么我错过了什么,或者这个代码是错误的?

我期望这个插值搜索根据公式的逻辑将数组分成两个,但似乎公式的输出总是i,i+1,i+2,.

推荐答案

你没算对pos.您在表达式中过早地使用了整数除法--您必须先做乘法,然后再除法.如果你先做除法,在乘法之前会四舍五入,你就会失go 精度.

它还导致在搜索数组中的最后一个元素时出现被零除的错误.

def interpolation_search(ar:list, lo:int, hi:int, x:int):
    if (lo <= hi and x >= ar[lo] and x <= ar[hi]):
        pos = lo + ((hi - lo) * (x - ar[lo])) // (ar[hi] - ar[lo])

        print(pos)

        if ar[pos] == x:
            return pos

        if ar[pos] < x:
            return interpolation_search(ar, pos + 1, hi, x)

        if ar[pos] > x:
            return interpolation_search(ar, lo, pos - 1, x)

    return -1

Python相关问答推荐

判断两极中N(N 2)列水平是否相等

将列表中的元素替换为收件箱中的元素

code _tkinter. Tcl错误:窗口路径名称错误.!按钮4"

如果索引不存在,pandas系列将通过索引获取值,并填充值

用gekko解决的ADE方程系统突然不再工作,错误消息异常:@错误:模型文件未找到.& &

如何处理嵌套的SON?

使用numpy提取数据块

为什么tkinter框架没有被隐藏?

如何将双框框列中的成对变成两个新列

如何使用LangChain和AzureOpenAI在Python中解决AttribeHelp和BadPressMessage错误?

我们可以为Flask模型中的id字段主键设置默认uuid吗

Godot:需要碰撞的对象的AdditionerBody2D或Area2D以及queue_free?

优化器的运行顺序影响PyTorch中的预测

如何根据一列的值有条件地 Select 前N个组,然后按两列分组?

joblib:无法从父目录的另一个子文件夹加载转储模型

AES—256—CBC加密在Python和PHP中返回不同的结果,HELPPP

Python—压缩叶 map html作为邮箱附件并通过sendgrid发送

关于两个表达式的区别

pandas:在操作pandora之后将pandora列转换为int

我对这个简单的异步者的例子有什么错误的理解吗?