【问题标题】:Count the number of opertations inside a recursive algorithm in python计算python中递归算法中的操作数
【发布时间】:2017-02-26 03:50:01
【问题描述】:

我正在 python 中实现 二分搜索 算法,在第二个版本的函数中我必须(除了根据元素的存在与否返回真或假)计数算法完成的操作(比较)的数量取决于我正在使用的列表的长度并返回它。

但是,我的函数是递归的,自然我必须将计数器变量(将在每次操作时递增)初始化为零。问题是这个变量在每次递归调用时都会取零值,因此它不会给我正确的值。我想到了一个全局变量,但我不知道如何使用它。

这是我的函数的代码:

def trouve(T, x) :      
  if len(T) == 0 :
    return False 
  mid = len(T) // 2
  if T[mid] == x :
    return True
  if len(T) == 1 and T[0] != x  : 
    return False
  else :
    if x > T[mid] :
      return trouve(T[mid:], x)
    else :
      return trouve(T[:mid], x)

【问题讨论】:

  • 唯一算作比较的操作是x > T[mid]?什么是 - 根据您的比较?
  • 操作数和 ==
  • 为什么不定义一个global var (gasp) 并增加它?
  • 你也可以试试"static"
  • @bytesized 啊是的,你是对的。我修改了我的建议以包含一个链接

标签: python algorithm recursion


【解决方案1】:

通常,您只会计算数据的比较,而不是比较输入列表长度的条件。

您可以使用第三个参数来累积计数,然后让函数返回一个包含成功和计数的元组:

def trouve(T, x, c = 0):
  if len(T) == 0:
    return (False, c) # len() comparisons do not count 
  mid = len(T) // 2
  if T[mid] == x:
    return (True, c+1)
  if len(T) == 1: # you don't need to compare x again here! 
    return (False, c+1)
  # you don't need `else` here
  if x > T[mid]:
    return trouve(T[mid:], x, c+2)
  # you don't need `else` here
  return trouve(T[:mid], x, c+2)

print (trouve([1,3,8,13,14,15,20], 14))

注意,你可以优化一下:

def trouve(T, x, c = 0):
  if len(T) == 0:
    return (False, c) 
  mid = len(T) // 2
  # you don't need the `len(T) == 1` case, as it can be 
  # treated in the recursive call. See change below:
  if x > T[mid]:
    return trouve(T[mid+1:], x, c+1) # exclude mid itself
  # Move equality test below greater-then test, since the 
  # equality has little chance of being true:
  if T[mid] == x:
    return (True, c+2)
  return trouve(T[:mid], x, c+2)

print (trouve([1,3,8,13,14,15,20], 14))

...虽然对于我给出的示例,这个版本的计数仍然相同。

【讨论】:

    【解决方案2】:

    如果你想走全局变量路线(因为你提到过),你会这样做。

    trouve_count = 0
    def trouve(T, x) :
      global trouve_count
      # Increment trouve_count like this when necessary:
      trouve_count += 1
      # ...
    

    在较大的程序中使用它们时要小心,因为您可能会不小心使用相同的全局名称两次,从而导致问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-08
      • 1970-01-01
      • 2012-12-12
      相关资源
      最近更新 更多