【问题标题】:Is there a way to write a recursive function that looks through all the integers in a list and sees if any two are equal to a negative sum?有没有办法编写一个递归函数来查看列表中的所有整数并查看是否有两个等于负和?
【发布时间】:2014-10-10 22:33:12
【问题描述】:

所以问题是,你有一个整数列表,你必须找出列表中的任何两个总和是否为负数。

我现在有这个

def negsum(L):
    if len(L) <= 2:
        if L[0] + L[1] >= -1: #Here is my base case
            return False
        else:
            return True
    else: 
        if L[0] + L[1] <= -1:
            return True
        else:
            return negsum(L[1:]) #Recursive portion

我的代码的问题是它只检查列表中的前 2 个。所以在一个列表中 [-10, 15, 30, -5] 当它应该为真时,你会得到 False,因为 -5 + -10 是负数。我的功能只检查:

-10 + 15

15 + 30

30 - 5

我怎样才能得到它,以便它使用递归检查 -10 + 30、-10 -5 和 15-5?

编辑,我忘了提,只允许使用 len() [] 和 : 运算符。没有循环。这甚至可以在没有循环的情况下实现吗?

【问题讨论】:

  • 您不只是对它们进行排序并检查两个最小值之和是否为&lt;0吗?
  • 或者如果算法复杂性是最重要的,return sum(heapq.nsmallest(2,L)) &lt; 0

标签: python recursion


【解决方案1】:

这是一种方法:

def negsum(L):
    if len(L)<2: return False
    if len(L) == 2:
        if sum(L)<0: return True
        else: return False
    for i,elem in enumerate(L):
        if elem < 0:
            return negsum(L[i+1:]+[elem])

输出:

In [39]: negsum([1,2,3,4,5])
Out[39]: False

In [40]: negsum([-1,2,3,4,5])
Out[40]: False

In [41]: negsum([-1,2,3,-4,5])
Out[41]: True

【讨论】:

    【解决方案2】:

    这个想法是将列表分成两部分:第一个元素L[0] 和其余的L[1:] 并将函数递归地应用于L[1:] 部分:

    def negsum(L):
        if len(L) == 2:     # base case
            return True if L[0] + L[1] < 0 else False 
        elif negsum(L[1:]): # recursion on the L[1:] part
            return True
        else:               # check L[1:] part pairwise against the first element
            return any(x + L[0]<0 for x in L[1:])
    

    【讨论】:

      【解决方案3】:

      这是一个没有循环(隐式或显式)的解决方案:

      def negsum(lst, sub=True):
          return len(lst) > 1 \
              and ((lst[0] + lst[1]) < 0
                      or negsum([lst[0]]+lst[2:], False)
                      or (sub and negsum(lst[1:])))
      

      或者,或者,以下版本将流程更清晰地分离为 2 个子功能,并且不需要额外的参数 'sub':

      def negsum(lst):
          def first_with_others(lst): # compare lst[0] with all later values
              if len(lst) > 1:
                  #print("summing", lst[0], "and", lst[1])
                  return ((lst[0] + lst[1]) < 0) or first_with_others([lst[0]]+lst[2:])
          def drop_first(lst): # successively drop first element
              if lst:
                  return first_with_others(lst) or drop_first(lst[1:])
          return drop_first(lst) or False # converts None to False
      

      取消对 print 函数的调用的注释会显示计算的总和:

      >>> negsum([1,2,3,4,5])
      summing 1 and 2
      summing 1 and 3
      summing 1 and 4
      summing 1 and 5
      summing 2 and 3
      summing 2 and 4
      summing 2 and 5
      summing 3 and 4
      summing 3 and 5
      summing 4 and 5
      False
      >>> negsum([-1,2,3,4,5])
      summing -1 and 2
      summing -1 and 3
      summing -1 and 4
      summing -1 and 5
      summing 2 and 3
      summing 2 and 4
      summing 2 and 5
      summing 3 and 4
      summing 3 and 5
      summing 4 and 5
      False
      >>> negsum([-1,2,3,-4,5])
      summing -1 and 2
      summing -1 and 3
      summing -1 and -4
      True
      >>> negsum([-2,1])
      summing -2 and 1
      True
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-09-10
        • 2016-08-08
        • 2011-02-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多