递归方式打印三角形图案

0 投票
5 回答
91 浏览
提问于 2025-04-14 18:17

最近我在学习递归这样的概念,并尝试用这种方法来解决一些以前用迭代方式写的旧程序,比如打印三角形图案。例如:

*
**
***
****
*****

但是我得到的输出是:

*****
****
*** 
**  
*   
None
def itriangle(x):
    if x==0:
        return
    print("*",end="")
    itriangle(x-1)
def jtriangle(y):
    if y==0:
        return
    itriangle(y)
    print()
    jtriangle(y-1)
print(jtriangle(5))

这是我写的代码,首先我得到的是一个倒过来的三角形,其次最后一行返回了“None”。我该怎么解决这个问题呢?

补充:我已经修复了之前出现的“None”,那只是我写错了字母,但现在主要的问题是我得到的是一个倒三角形,我不知道该怎么解决。任何帮助都非常感谢。

5 个回答

0

一个递归过程有两个阶段:

  • 调用阶段(向基本情况靠近),
  • 返回阶段(从基本情况回来)。

递归调用之前放的命令会在下行时执行(调用阶段),而在递归调用之后放的命令会在上行时执行(返回阶段)。

def downward(n):
    if n <= 0: return
    print(n * '*')     # executed before recursive call
    downward(n-1) 

def upward(n):
    if n <= 0: return
    upward(n-1)
    print(n * '*')     # executed after recursive call

例子:

>>> downward(5)
*****
****
***
**
*
>>> upward(5)
*
**
***
****
*****
>>>
1

关于为什么最后会得到 None:这是因为 print(jtriangle(5)) 这行代码是在打印 jtriangle(5) 函数的返回值,而这个返回值默认是 None,因为函数里面没有明确的 return 语句。这个函数自己已经处理了所有需要打印的内容,所以你其实不需要再打印函数的结果。你可以直接调用 jtriangle(5),而不需要加上 print

0

递归可能会让人感到困惑。我通常用自然语言来确保我写的递归程序是正确的。我可以这样说:

要打印一个大小为 n 的三角形,首先打印一个大小为 n-1 的三角形,然后再打印一行大小为 n 的线。

然后直接把它转换成代码:

def triangle(n):
    if n==0:
        return
    triangle(n-1)
    print()
    line(n)

注意:像 jtriangleitriangle 这样的名字并不能很好地传达意思。它们只会让你更加困惑,而递归本身就已经够复杂了,所以最好使用有意义的名字!


在开发递归程序时,我还使用了另一个强大的技巧(其实我总是这样做,但在使用递归时特别有帮助):采用自下而上的开发方式!也就是说,确保你的低层函数真的能正常工作且没有错误,开发高层函数之前。

在我上面的例子中,确保 line 函数能正常工作,然后再为 triangle 函数写代码。如果低层函数有错误,递归会让你很麻烦,而且调试起来会更加困难。

撰写回答