算法学习指南
上QQ阅读APP看书,第一时间看更新

观察程序清单1-1展示的存在缺陷的Python实现,它试图在一个至少包含1个值的任意列表中查找最大值。它所采用的方法是把A中的每个值与my_max进行比较,如果发现一个更大的值就更新my_max

程序清单1-1 在列表中查找最大值的算法的一种存在缺陷的实现

def flawed(A):
  my_max = 0          ❶
  for v in A:         ❷
    if my_max < v:
      my_max = v      ❸
  return my_max

my_max是保存最大值的变量,在这里my_max被初始化为0。

for循环定义了变量v,用于对A中的每个元素进行迭代。对v的每个值均执行一次if语句。

❸ 如果v更大,就更新my_max

这个实现的核心是对两个数进行比较以确定其中一个值是否小于另一个值的小于操作。在图1-3中,当v依次从A中取连续的值时,我们可以看到my_max被更新了3次,从而确定了A中的最大值。flawed()函数用于确定A中的最大值,调用了6次小于操作,对每个值各调用1次。在一个规模为N的问题实例中,flawed()调用N次小于操作。

图1-3 flawed()的执行示意

这个实现存在缺陷,因为它假设A中至少有一个值大于0。计算flawed([–5,–3,–11])时将返回0,这是不正确的。一种常见的弥补方法是把my_max初始化为可能出现的最小值,例如my_max =float('-inf')。这个方法仍然存在缺陷,因为如果A是空列表[],它就会返回这个值。现在,让我们修正这个缺陷。

图标1Python语句range(x, y)可以产生xy(包括x,但不包括y)的整数。我们也可以采用range(x,y,–1)的形式,它将产生从x向下计数到y(但不包括y)的整数。因此,list(range(1,7))的结果是[1,2,3,4,5,6]list(range(5,0,–1))的结果是[5,4,3,2,1]。我们可以按照任意的步长进行计数,比如list (range(1,10,2))采用差值为2的步长,结果是[1,3,5,7,9]