C代码的Python翻译不起作用

C代码的Python翻译不起作用,python,c,algorithm,divide-and-conquer,Python,C,Algorithm,Divide And Conquer,我想使用分治法在O(logn)time中找到数组中的最大元素。我在上找到了一个工作代码。我将其翻译为Python,如下所示: def largest(arr,i,j): global max1 global max2 if i == j: max1 = arr[i] else: if i == j-1: max1 = arr[i] if arr[i] > arr[j] else arr[j]

我想使用分治法在
O(logn)
time中找到数组中的最大元素。我在上找到了一个工作代码。我将其翻译为Python,如下所示:

def largest(arr,i,j):
    global max1
    global max2
    if i == j:
        max1 = arr[i]
    else:
        if i == j-1:
           max1 = arr[i] if arr[i] > arr[j] else arr[j]
        else:
              mid = (i+j)/2
              largest(arr,i,mid)
              max2 = max1
              largest(arr,mid+1,j)
              if max2 > max1:
             max1 = max2
当我使用一个数组
[98,5,4,3,2,76,78,92]
时,将代码称为

max1 = arr[0]
largest(arr,1,8)

我得到一个越界列表索引错误。但是,C代码返回正确的结果98。有人能发现我在做什么错误吗?

您将最终得到一个函数调用

largest(arr, 7,8)
然后你的代码

max1 = arr[i] if arr[i] > arr[j] else arr[j]
将尝试索引arr[j]=arr[8] 这是不允许的,因为Python从0-7而不是1-8枚举向量


顺便说一句,我认为您没有O(logn)算法,因为所有元素都必须至少扫描一次才能找到最大元素,从而得到O(N)。

您将最终得到一个函数调用

largest(arr, 7,8)
然后你的代码

max1 = arr[i] if arr[i] > arr[j] else arr[j]
将尝试索引arr[j]=arr[8] 这是不允许的,因为Python从0-7而不是1-8枚举向量


顺便说一句,我认为您没有O(logn)算法,因为所有元素都必须至少扫描一次才能找到最大元素,从而得到O(N)。

对于一般未排序的数组,您永远无法在少于O(N)的时间内找到
max
。一个非常简单的证明:如果在不到O(n)的时间内完成,那么对于足够大的数组,就没有足够的时间检查每个元素。因此,对手可以将最大值放在您未检查的元素中,从而使您的算法不正确

原始代码的优点是使用少于2n个比较同时查找最大值和最小值(就像naive实现所做的那样)——它使用大约1.5n个比较,因为当有两个元素时,它只执行一个比较。使用它只找到最大值并没有什么好处:您最好改用Python中的
max(arr)
(因为它没有函数调用开销,所以速度也会更快)

原始代码将值存储在
a[1]
a[n]
中,这需要一个大小为
n+1
的数组。因此,您应该在第一个位置放置一个虚拟元素

但是,更麻烦的是,你的翻译是错误的。最初的版本使用全局变量来实现多值返回(这是一种非常粗糙的方法),使用局部变量来保存旧的全局变量。由于将
max1
max2
设置为全局,因此该函数无论如何都不会生成正确的答案

正确的Python转换将使用直接多值返回和元组:

def minmax(arr, i, j):
    if i==j:
        return arr[i], arr[i]
    elif i==j-1:
        if arr[i] < arr[j]:
            return arr[i], arr[j]
        else:
            return arr[j], arr[i]
    else:
        mid = (i+j)//2
        min1, max1 = minmax(arr, i, mid)
        min2, max2 = minmax(arr, mid+1, j)
        if min2 < min1: min1 = min2
        if max2 > max1: max1 = max2
        return min1, max1
def最小值(arr,i,j):
如果i==j:
返回arr[i],arr[i]
elif i==j-1:
如果arr[i]max1:max1=max2
返回min1,max1

对于一般未排序的数组,在任何小于O(n)的时间内都无法找到
最大值。一个非常简单的证明:如果在不到O(n)的时间内完成,那么对于足够大的数组,就没有足够的时间检查每个元素。因此,对手可以将最大值放在您未检查的元素中,从而使您的算法不正确

原始代码的优点是使用少于2n个比较同时查找最大值和最小值(就像naive实现所做的那样)——它使用大约1.5n个比较,因为当有两个元素时,它只执行一个比较。使用它只找到最大值并没有什么好处:您最好改用Python中的
max(arr)
(因为它没有函数调用开销,所以速度也会更快)

原始代码将值存储在
a[1]
a[n]
中,这需要一个大小为
n+1
的数组。因此,您应该在第一个位置放置一个虚拟元素

但是,更麻烦的是,你的翻译是错误的。最初的版本使用全局变量来实现多值返回(这是一种非常粗糙的方法),使用局部变量来保存旧的全局变量。由于将
max1
max2
设置为全局,因此该函数无论如何都不会生成正确的答案

正确的Python转换将使用直接多值返回和元组:

def minmax(arr, i, j):
    if i==j:
        return arr[i], arr[i]
    elif i==j-1:
        if arr[i] < arr[j]:
            return arr[i], arr[j]
        else:
            return arr[j], arr[i]
    else:
        mid = (i+j)//2
        min1, max1 = minmax(arr, i, mid)
        min2, max2 = minmax(arr, mid+1, j)
        if min2 < min1: min1 = min2
        if max2 > max1: max1 = max2
        return min1, max1
def最小值(arr,i,j):
如果i==j:
返回arr[i],arr[i]
elif i==j-1:
如果arr[i]max1:max1=max2
返回min1,max1

您没有使用完全相同的代码。C代码有3个If语句,并且该代码在O(lgn)时间内没有找到最小值和最大值;事实上,这是不可能的。它至少需要线性时间,简单的线性扫描可能会更快。你应该调用
最大(arr,0,7)
或者
最大(arr,1,7)
@IonutHulub:如果数组被排序,你可以在O(1)中完成。每次你在python中使用global,程序员都会发现你没有使用完全相同的代码。C代码有3个If语句,并且该代码在O(lgn)时间内没有找到最小值和最大值;事实上,这是不可能的。它至少需要线性时间,简单的线性扫描可能会更快。您应该调用
最大(arr,0,7)
或者
最大(arr,1,7)
@IonutHulub:如果数组被排序,您可以在O(1)中完成。每次您在python中使用global时,程序员都会按照他们的方式在python中使用
m,m=min(arr),max(arr)
对于任何实际大小的数组(在一般情况下)都比该算法快,因为这两个函数都是用C.An编写的