递归打印数字金字塔

5
我需要打印一个数字金字塔,遵循以下规则: 奇数索引:从1到索引, 偶数索引:从索引到1。
1
21
123
4321
12345
654321
1234567
87654321
123456789
我写了下面这段代码:

def printFigure(rows):
    if rows > 0:
        if rows%2 == 0:
            printFigure(rows-1)
            while(rows>0):
                print(str(rows)[::-1], end = '')
                rows -= 1
            print('')

        if rows%2 == 1:
            printFigure(rows-1)
            while (rows>0):
                print(str(rows),end = '')
                rows -= 1
            print('')
但输出结果是:
1
21
321,
4321
54321
654321
7654321
87654321
987654321

我是一名递归的初学者,希望能够得到您的解释。

谢谢。


2
你需要使用递归吗? - Dani Mesejo
1
print('\n'.join([''.join(map(str, range(1, n+1)[::(-1)**(n%2)])) for n in range(1, 10)])) - Ma0
1
@Ev.Kounis (1,-1)[n%2] :D - Mateen Ulhaq
@MateenUlhaq 不过,字节数是一样的,对吧?不过很好! - Ma0
@Ev.Kounis 如果我们在打高尔夫球,我认为这是我能做到的最短的代码:print('\n'.join('123456789'[:n][::(-1,1)[n%2]]for n in range(1,10))) - Mateen Ulhaq
1
@MateenUlhaq n%2*2-1,在Python2中你可以省略括号。而range(9)则是:print'\n'.join('123456789'[:n+1][::1-n%2*2]for n in range(9)) - zch
5个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
4
您当前的代码存在两个主要问题。首先,在递归调用printFigure之后,应该检查rows是偶数还是奇数。原因是在从递归调用中退出后,您希望决定按顺序还是倒序打印行。 第二个问题出现在else打印条件的逻辑上。您需要从1开始打印,直到行数为止。我使用了一个虚拟变量来实现这一点,但可能还有其他几种方法。
def printFigure(rows):
    if rows > 0:
        printFigure(rows-1)
        if rows%2 == 0:
            while(rows>0):
                print(str(rows)[::-1], end='')
                rows -= 1
            print('')
        else:
            i = 1
            while (i <= rows):
                print(str(i), end='')
                i += 1
            print('')

printFigure(9)

1
21
123
4321
12345
654321
1234567
87654321
123456789

1
@BenjaminYakobi 如果这个答案对您有帮助,您应该接受它,对于其他搜索相同问题的人也会有帮助。 - Brown Bear

3
你可以使用一个从底部到顶部打印的内部函数,并从外部函数中调用该函数,例如:

您可以使用一个从下到上打印的内部函数,然后从外部函数调用该函数,例如:

def print_rows(n, limit):
    if n < limit:
        numbers = range(1, n + 1) if n % 2 == 1 else reversed(range(1, n + 1))
        print(''.join(map(str, numbers)))
        print_rows(n + 1, limit)


def print_pyramid_recursive(n):
    if n > 0:
        print_rows(1, n)


print_pyramid_recursive(10)

输出

1
21
123
4321
12345
654321
1234567
87654321
123456789
在这种情况下,内部函数是print_rows,外部函数是print_pyramid_recursive。请注意,这个问题有一个非常简单的非递归解决方案,例如:
def print_pyramid(n):
    for i in range(1, n + 1):
        numbers = range(1, i + 1) if i % 2 == 1 else reversed(range(1, i + 1))
        print(''.join(map(str, numbers)))

3

如果您不需要使用递归,其他简单的解决方案是:

def printFigure(rows): 
    for x in range(rows): 
        items = [str(i) for i in range(1, x + 1)] 
        if x % 2 == 0: 
            items = items[::-1] 
        print(''.join(items))

非常简短,比我的代码简单得多。 - Benny
很高兴你喜欢它) - Brown Bear

2

这是最简单的循环版本:

is_reversed = False
for i in range(1, 10):
    step = -1 if is_reversed else 1
    print(''.join(map(str, range(1, i + 1)))[::step])
    is_reversed = not is_reversed

每次迭代都会重新生成一个字符串。我们还可以存储先前结果的值,并在其基础上构建:

s = ''
is_reversed = False
for i in range(1, 10):
    s += str(i)
    step = -1 if is_reversed else 1
    print(s[::step])
    is_reversed = not is_reversed
当然,这个函数可以很容易地(但毫无意义地)通过传递堆栈来转换为尾递归函数:
def f(s, i, max_i, is_reversed):
    if i == max_i:
        return
    s += str(i)
    step = -1 if is_reversed else 1
    print(s[::step])
    is_reversed = not is_reversed
    i += 1
    f(s, i, max_i, is_reversed)

f('', 1, 10, False)
每个看起来越来越奇怪的代码段的结果:
1
21
123
4321
12345
654321
1234567
87654321
123456789

谢谢你!这是我的作业,我的函数只能接收一个参数,但我会写下这个解决方案来进行自学。 - Benny

1
你可以使用简单的递归:
def print_pyramid(_count = 1):
  if _count < 10:
    print((lambda x:x[::-1] if not _count%2 else x)(''.join(map(str, range(1, _count+1)))))
    print_pyramid(_count+1)


print_pyramid()

输出:

1
21
123
4321
12345
654321
1234567
87654321
123456789

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,