Python 3.x 为函数查找只有一个输入(数组)的固定点

Python 3.x 为函数查找只有一个输入(数组)的固定点,python-3.x,binary-search,fixed-point-iteration,Python 3.x,Binary Search,Fixed Point Iteration,我试图使用一个只接受一个输入(数组)的函数在数组中找到一个固定点。问题是,我试图避免构建这个函数可以调用的另一个函数。如果我能做到这一点,这种情况就会得到解决。这些数组将包含一个排序整数列表,供我遍历。我试图通过使用二进制搜索来保持它的运行时间较低。我已经尝试了100种不同的方法,但是没有什么是有效的 def fixed_point(a): if len(a) <= 2: # tried len(a) == 0 and len(a) == 1 return

我试图使用一个只接受一个输入(数组)的函数在数组中找到一个固定点。问题是,我试图避免构建这个函数可以调用的另一个函数。如果我能做到这一点,这种情况就会得到解决。这些数组将包含一个排序整数列表,供我遍历。我试图通过使用二进制搜索来保持它的运行时间较低。我已经尝试了100种不同的方法,但是没有什么是有效的

def fixed_point(a):    

    if len(a) <= 2: # tried len(a) == 0 and len(a) == 1
        return -1 

    mid = len(a)//2 # have used (len(a)-1)//2 as well

    if mid == a[mid]:
        return a[mid]

    if mid > a[mid]:
        return find_point(a[mid+1:])

    else:
        return find_point(a[:mid])

    return -1
def固定点(a):
如果len(a)a[mid]:
返回查找点(a[mid+1:])
其他:
返回查找点(a[:中间])
返回-1
如果没有找到固定点,此函数将返回-1

此函数还通过了为此构建的10000个测试,但由于某种原因,无法找到“5”是数组的固定点:[-10,-5,-2,2,3,5,7,10,15,25,35,78,129]


好奇人们可能会发现这个代码有什么错误

编写的算法的基本问题是,您无法知道自己在原始数组中的位置。当您递归时,返回数组一半的固定点,但例如在
[-4,-2,0,2,4]
中,当您拆分数组并在
[2,4]
中找到固定点时,它不起作用,因为
[2,4]
中没有固定点。您需要在每个递归调用中传递一个偏移量,这样您就可以说,如果mid+offset==a[mid],要重复我在评论中所说的,问题是您正在失去对
a
的跟踪

您的方法是递归的,每次调用时都会传递一个大小不断缩小的列表。正因为如此,你寻找的中间层和你最终比较的中间层并不相同

切换到迭代方法,您可以将事情保持在原始
a
的上下文中

def fixed_point(a):
    l, u = 0, len(a)

    while l <= u:
        m = (l + u) // 2
        if m == a[m]:
            return m
        elif m > a[m]:
            l = m + 1
        else:
            u = m - 1

    return -1

迭代还有一个好处,就是内存开销更小(不需要调用堆栈),尽管在其他语言上,一些编译器会进行优化。

Ugh,我是个白痴。为了便于阅读,我删除了“fixed”一词。否则,在我的原始代码中找不到这种打字错误。我已经做了好几个小时了。我将修正您要查找的
mid
是相对于原始数组的中点,对吗?当你切片列表并将其传递给下一个调用时,大小会发生变化,因此之后所有if条件都不会为真,因为你要查找的中间值和你最终比较的中间值将不同。顺便说一句,我对“固定点”的理解是,值的索引等于值。。。对吧?嗯,这很有道理。我想我需要考虑如何解决这个问题……是的,一个值的索引需要等于它的值@coldspeedWow,这就更有意义了。我在想什么。。。。谢谢你的帮助。真不敢相信我会忽视这样的事情。我真的很感激澄清我的方法是如何错误的。非常感谢。
>>> fixed_point([-10, -5, -2, 2, 3, 5, 7, 10, 15, 25, 35, 78, 129])
5