带递归的帕斯卡三角形

时间:2017-04-28 19:45:43

标签: python recursion pascals-triangle

好的,有人可以告诉我,我的当前代码是否可行。我必须使用输入创建pascals三角形而不使用任何循环。我一定会递归。

我花了3天时间,这是我能想到的最好的输出。 它驱使我INSANE

def pascal(curlvl,newlvl,tri):

  if curlvl == newlvl:
    return ""

  else:

    tri.append(tri[curlvl])

    print(tri)
    return pascal(curlvl+1,newlvl,tri)


def triLvl():
  msg = "Please enter the number of levels to generate:"

  triheight = int(input(msg))

  if triheight < 1:
    print("\n Sorry, the number MUST be positive\n Please try again.")
    return triLvl()

  else:
    return triheight



def main():

   triangle = [1]

   curlvl = 0

   print("Welcome to the Pascal's triangle generator.")

   usrTri = triLvl()
   print(triangle)
   pascal(curlvl,usrTri,triangle)



main()

3 个答案:

答案 0 :(得分:1)

我们可以使用辅助函数pascal

定义递归pairs

pascal将返回[[Int]](Int数组数组) - 例如,pascal(3)将返回

[ [1],
  [1, 1],
  [1, 2, 1] ]

好的,所以我会事先向你展示所有代码,但之后我会逐步解释某些内容

def pairs (xs):
  if 2 > len(xs):
    return []
  else:
    return [xs[0:2]] + pairs(xs[1:])

def pascal (n):
  def compute (prev):
    return [1] + [x + y for (x,y) in pairs(prev)] + [1]
  def aux (m, prev):
    if (m > n):
      return []
    else:
      return [prev] + aux(m + 1, compute(prev))
  return aux(1, [1])

[print(line) for line in pascal(5)]
# [1]
# [1, 1]
# [1, 2, 1]
# [1, 3, 3, 1]
# [1, 4, 6, 4, 1]

<强>解释

我们真正关心的是pascal功能 - 我们编写的所有其他内容都是出自我们编写pascal的方式而产生的,所以我将首先介绍一下

编写递归函数的一种非常常见的方法是使用内部辅助函数来跟踪我们的计算的各种状态。我们将使用此技术作为pascal函数

的基础
def my_recursive_func (<parameters>):
  def aux (<state_parameters>):
    if (<base_condition>):
      return <base_value>
    else
      return aux(<updated_state>)
  return aux(<initial_state>)

我们已经知道如何为pascal函数

填写一些样板文件
  • parameters应该只是n,一个整数,因为我们希望调用我们的函数,如pascal(3)pascal(5)等 - 不应该接受其他参数
  • state_parameters - 我们现在只知道两件事:1)我们需要一些值m的值n,每次递增1 - 并且2)允许我们计算下一行的一些值;我们将其称为prev,因为每个pascal行都是根据上一行行计算的
  • base_condition - 当m == n我们知道我们已经生成了我们需要的所有行时,这就是我们想要停止递归的时间
  • base_value - 这是最后返回的值 - 不太确定应该是什么
  • updated_state - 我们将使用m更新m + 1,我们将使用某种数组连接更新行 - 在我们编写更多代码之前不确定
  • initial_state - 我们将在m开始1,第一行pascal为[1]

好的,让我们填写到目前为止的内容

def pascal (n):
  def aux (m, prev):
    if (m > n):
      return ?
    else:
      return aux(m + 1, ?)
  return aux(1, [1])

我们要做的是让pascal构建我们的结果

[[1]] + [[1, 1]] + [[1, 2, 1]] + [[1, 3, 3, 1]], ...]
# => [ [1], [1 ,1], [1, 2, 1], [1, 3, 3, 1], ... ]

因此,为了为base_value编写prev和更新状态,我们需要考虑此返回类型。我们想要返回[[Int]]这是一个列表,因此base_value可以只是空列表[]

这意味着在每一步中,我们实际上都想要[prev]并将其连接(+)到递归结果......

[prev] + aux(m + 1, <next_row>)

我们现在变得非常接近,让我们再次更新pascal以了解我们必须完成的工作

def pascal (n):
  def aux (m, prev):
    if (m > n):
      return []
    else:
      return [prev] + aux(m + 1, <next_row>)
  return aux(1, [1])

好的,所以这里有硬盘 - 计算下一排吧?嗯,实际上并不太糟糕。

# given
[1,2,1]

# the next row is
[1, (1 + 2), (2 + 1), 1]

或另一个例子

# given
[1, 4, 6, 4, 1]

# the next row is
[1, (1 + 4), (4 + 6), (6 + 4), (4 + 1), 1]

所以模式是这样的:创建一个以1开头的新数组,然后对于前一行中的每对数字,将两个数字加在一起并将每个和附加到数组中,然后最后追加另一个1。我们可以在python中表达,就像使用像这样的列表理解

[1] + [x + y for (x,y) in pairs(prev)] + [1]

现在我们只需要找出pairs函数。 pairs应该有以下合同

pairs([])        => []
pairs([a])       => []
pairs([a,b])     => [[a,b]]
pairs([a,b,c])   => [[a,b],[b,c]]
pairs([a,b,c,d]) => [[a,b],[b,c],[c,d]]

现在让我们实施它并验证我们的实施是否符合合同。请注意,我在pascal 之外实现了这个函数,因为它是一个通用函数并且本身很有用。要计算pascal行,我们需要添加数字对,但添加或 我们得到这些对或数字不应该作为pascal函数本身的责任。

def pairs (xs):
  if 2 > len(xs):
    return []
  else:
    return [xs[0:2]] + pairs(xs[1:])

print(pairs([]))        # []
print(pairs([1]))       # []
print(pairs([1,2]))     # [[1,2]]
print(pairs([1,2,3]))   # [[1,2],[2,3]]
print(pairs([1,2,3,4])) # [[1,2],[2,3],[3,4]]
好的,现在让我们真的很近了。让我们再次更新pascal功能以查看我们在

的位置
def pascal (n):
  def aux (m, prev):
    if (m > n):
      return []
    else:
      return [prev] + aux(m + 1, [1] + [x + y for (x,y) in pairs(prev)] + [1])
  return aux(1, [1])

圣洁的烟!我们已经完成了。使用内联计算下一行的aux调用看起来有点繁忙。让我们在名为pascal的{​​{1}}内添加另一个帮助程序来清理。现在我们已经完成了!

compute

彻底

如果您想要显示那些愚蠢的文字和提示,您可以写下def pascal (n): def compute (prev): return [1] + [x + y for (x,y) in pairs(prev)] + [1] def aux (m, prev): if (m > n): return [] else: return [prev] + aux(m + 1, compute(prev)) return aux(1, [1])类似的内容 - 这样可以使所有I / O与我们的mainpascal功能分开。这种关注点的分离和副作用的管理对于在程序的早期考虑很重要,因为很难重复使用比我们想要的更多的功能。

pairs

继续并运行def main (): try: print("Pascal triangle generator") n = int(input("Pascal(x): x = ")) if n < 1: raise [print(line) for line in pascal(n)] except: print("enter a non-zero positive integer") main() # run program main() 或其他东西以获得一些令人印象深刻的结果

答案 1 :(得分:0)

我不知道这是否是您正在寻找的,但它的工作正常:

from operator import add


def pascal(curlvl, newlvl, tri):
    if curlvl == newlvl:
        return ""
    elif curlvl == 0:
        tri.append(1)
        print (tri)
        return pascal(curlvl + 1, newlvl, tri)
    else:
        tmp = [1]
        rt = tri[:-1]
        rt.reverse()
        # print (map(add, rt, tri[:-1]))
        # In Python 3, map returns a generator.
        # Wrapping map in list makes this code compatible with
        # both Python 2 and 3
        tt = list(map(add, rt, tri[:-1]))
        if (len(tt) > 0):
            tmp.extend(tt)
        tmp.append(1)
        tri = tmp
        print (tri)
        return pascal(curlvl + 1, newlvl, tri)


def triLvl():
    msg = "Please enter the number of levels to generate:"

    triheight = int(input(msg))

    if triheight < 1:
        print("\n Sorry, the number MUST be positive\n Please try again.")
        return triLvl()

    else:
        return triheight


def main():
    triangle = [1]

    curlvl = 0

    print("Welcome to the Pascal's triangle generator.")

    usrTri = triLvl()
    print(triangle)
    pascal(curlvl, usrTri, triangle)


main()

答案 2 :(得分:0)

递归Pascal三角形作为列表:

P=lambda h:(lambda x:x+[[x+y for x,y in zip(x[-1]+[0],[0]+x[-1])]])(P(h-1))if h>1 else[[1]]
print(P(10))

我希望它可以提供帮助,我不知道是否可以提供拉链。和&#39; map&#39;被认为是循环(它们当然包含循环)。