О генерации скобочных последовательностей

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Всем доброго времени суток!

Эта коротенькая заметка посвящена симпатичной задачке генерации в лексикографическом порядке всех правильных скобочных последовательностей. Её нередко включают в список задач для подготовки к собеседованию (например, здесь).

По просторам инета гуляет следующее решение:

def  gen_parentheses(parentheses_count, str_, left, right, out_file):
    if left == parentheses_count and right == parentheses_count:
        out_file.write(str_ + "\n")
    return
    if left < parentheses_count:
        gen_parentheses(parentheses_count, str_ + "(", left + 1, right, out_file)
    if right < left:
        gen_parentheses(parentheses_count, str_ + ")", left, right + 1, out_file)

with open("input.txt") as in_file:
    parentheses_count = int(next(in_file))
with open("output.txt", "w") as out_file:
    gen_parentheses(parentheses_count, "", 0, 0, out_file)

Оно, несмотря на его изящную простоту, вызывало чувство некоторой неудовлетворённости :). Присмотревшись, я понял, чем был вызван мой творческий зуд :) –подсознательно не нравилось, что на добавление каждой скобки требовался отдельный вызов функции. Конечно, хотелось бы сократить глубину рекурсии. Сделать это оказалось совсем не сложно.

Ну, во-первых, очевидно, что если число добавленных открывающихся скобок достигло заданного, то нет смысла добавлять соответствующие закрывающиеся скобки по одной – можно сразу добавить все недостающие закрывающиеся скобки:

def  gen_parentheses_v1(parentheses_count, str_, left, right, out_file):
    if left < parentheses_count:
        gen_parentheses_v1(parentheses_count, str_ + "(", left + 1, right, out_file)
        if right < left:
            gen_parentheses_v1(parentheses_count, str_ + ")", left, right + 1, out_file)
        else:
            out_file.write(str_ + (parentheses_count-right)*")" + "\n")

А во-вторых, да и с открывающимися скобками можно не тормозить :) – добавлять не по одной, а сразу строкой из нескольких открывающихся скобок и одной закрывающейся:

def gen_parentheses_v2(parentheses_count, str_, left, right, out_file):
    if left < parentheses_count:
        for i in range(parentheses_count, max(left, right+1) - 1, -1):  
            gen_parentheses_v2(parentheses_count,
                               str_ + (i-left)*"(" + ")",
                               i,
                               right + 1,
                               out_file)
    else:
        out_file.write(str_ + (parentheses_count-right)*")" + "\n")

В итоге глубина рекурсии снизилась более чем в два раза :)

Источник: https://habr.com/ru/articles/742894/


Интересные статьи

Интересные статьи

Недавно мы рассказывали о том, что активно используем нейросети при работе над цифровыми сервисами. В новой статье мы поделимся результатами собственного сравнительного анализа нейросетей для генераци...
Инструкция по разработке TELEGRAM-бота, функционал которого позволяет сканировать и генерировать QR-коды.
Задача интеграции сервисов и различных систем является чуть ли не одной из основных проблем современного IT. На сегодняшний день самым популярным архитектурным стилем для...
11 декабря 2019 года (как раз накануне Дня Конституции) Государственная Дума Российской Федерации в третьем чтении приняла Федеральный закон «О внесении изменений в Федеральный закон «Об элек...
Несколько месяцев назад я закончил один из этапов своего профессионального пути многорукого Шивы в стартапе по разработке системы управления лабораториями неразрушающего контроля. Я расскажу ...