Могу ли я выполнить эту задачу без использования двух циклов? - PullRequest
0 голосов
/ 02 октября 2018

Я пытался решить простую проблему, чего я должен добиться: если значение n равно 2, выведите

2211
21

или если значение n равно3, print

333222111
332211
321

Что я кодировал, это:

n=3
for i in range(n,0,-1):
    for j in range(n,0,-1):
        print(str(j)*i,sep='',end='')
    print()

Есть ли способ выполнить эту задачу без двух циклов?

ИлиМогу ли я перебрать значение j с n до 0 без использования цикла и напечатать каждый вариант?

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Нет, на самом деле не существует способа сделать это с одним циклом, поскольку задача включает в себя двойной цикл, но вы можете сделать его более эффективным, например, использовать понимание списка для построения каждой строки, чтобы вы вызывали только print один раз в строке.

Вы могли бы использовать рекурсию, но это менее эффективно, и это на самом деле не устраняет цикл, оно просто реализует его по-другому.

Вот списоккомп версия вашего кода, обернутая в функцию.

def show_pattern(n):
    for i in range(n, 0, -1):
        print(''.join([str(j)*i for j in range(n, 0, -1)]))

FWIW, вот версия с одной строкой, которая несколько более эффективна, но, конечно, временная сложность все еще O (n²).И я думаю, вы согласитесь, что это немного сложнее читать.;)

print('\n'.join([''.join([str(j)*i for j in range(n, 0, -1)]) for i in range(n, 0, -1)]))

Можно утверждать, что сложность на самом деле O (n³), поскольку str(j)*i выполняется внутри цикла, но этот цикл работает на скорости C, поэтому мы можем притвориться, что этопримитивная операция.

0 голосов
/ 02 октября 2018

Вы можете сделать это с помощью рекурсии, но сложность времени не изменится ... Примерно так:

def method(n, size):
    if n == 0:
        return;
    for i in range(size,0,-1):
        print(str(i)*n,sep='',end='')
    print()
    method(n-1, size)

method(3, 3)
...