Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Скриптовые языки программирования > Python
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.02.2022, 03:44   #1
corpselles
 
Регистрация: 09.02.2022
Сообщений: 7
По умолчанию Python. Помощь в нахождении ошибки в простых функциях

Доброго времени суток!
Хотелось бы узнать, в чем заключается моя ошибка и какие вообще советы могли бы вы мне, начинающему программисту на Python, собственно, дать.

Суть программы(функции) вот в чем: она определяет правильную скобочную последовательность и выводит Yes or NO, соответсвенно. Также '' тоже будет являться верной скобочной последовательностью

Я добавил пару переменных, чтоб проще для меня(но, к сожалению, не для читателя, что я буду пытаться делать в некст задачах) работать с кодом.

Ошибка вот в чем: Вводится: bracket_check("()")
Видно, что верная последовательность, но программма все-равно выводит НЕТ

Код:
def bracket_check(test_string):
    ma = int(len(test_string))
    mi = int(ma / 2)
    ls = list(test_string)
    if test_string == '':
        print('YES')
    if ma >= 2 and ma % 2 == 0:
        k = 0
        middle1 = ma / 2 - 1
        middle2 = middle1 + 1
        for i in range(mi):
            if [middle1] in ls != [middle2] in ls:
                middle1 -= 1
                middle2 += 1
            else:
                k += 1
        if k == 0:
            print('YES')
        else:
            print('NO')
    else:
        print('NO')

Заранее всем огромное спасибо!! Принимаю любую объективную критику, хоть с ног до головы заливайте - без нее не будет прогресса)
corpselles вне форума Ответить с цитированием
Старый 09.02.2022, 04:22   #2
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Очень смущает этот for с if. Что вы хотели им проверить? Чтобы скобочная последовательность была верной, должно выполниться 2 условия: во всей строке количество открывающих и закрывающих скобок равно, на любой позиции строки количество уже встреченных открывающих скобок больше или равно количеству закрывающих. Примерно:
Код:
k = 0
for s in test_string:
    if s == '(':
        k += 1
    elif s == ')':
        k -= 1
        if k < 0:
            print('NO')
            break
else:
    if k == 0:
        print('YES')
    else:
        print('NO')
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 09.02.2022 в 04:25.
BDA вне форума Ответить с цитированием
Старый 09.02.2022, 14:44   #3
corpselles
 
Регистрация: 09.02.2022
Сообщений: 7
По умолчанию

BDA, Спасибо большое, я разобрался!! Своим for и if я хотел проверить догадку о следующей теории: Допустим, есть следующая скобочная последовательность: 1) "()" я брал, делил длину всей строки, попутно закидывая саму строку в список для удобства работы с ее элементами через доступ в позиции [0] и [1] в данном случае. Брал средних два числа, у одного просто вычитал, чтоб соответствовало порядку 0, 1, 2.... а не 1, 2, 3 и т.д. И вот, мы смотрим на эти два символа изнутри - ушки направлены в разные стороны(они разные), следовательно, пара будет верной. А в строках со скобочной последовательностью побольше я так же попарно их разбирал: 2) "((()))". Сначала мы, опять же, разбираем пару из цента, т.е "xx()xx" - верно? верно, идем дальше - теперь "x(xx)x"Я, закрыв предыдущую пару, разбираю следующую, равноудаленную от центра, и так , пока не дойдем до финишного. Просто глянул на примеры скобочных последовательностей и такой алгоритм проверки сам дошел ко мне в голову... может с более сложными случаями это будет не совсем корректно, но я выбрал именно такой вариант решения. Но благодаря вашему объяснению я понял задачу с другой стороны, более простой и логичной) Спасибо!
corpselles вне форума Ответить с цитированием
Старый 09.02.2022, 14:50   #4
ForenLi
Форумчанин
 
Регистрация: 02.06.2021
Сообщений: 515
По умолчанию

()() и ваш алгоритм ломается
ForenLi вне форума Ответить с цитированием
Старый 09.02.2022, 18:01   #5
ViktorR
Старожил
 
Регистрация: 23.10.2010
Сообщений: 2,309
По умолчанию

Есть такая книжка:
А. Шень, Программирование: теоремы и задачи, 2004

В этой книге есть более общий алгоритм решения задачи со скобками.
Когда-то, на этом форуме, выкладывал её решение на Pascal.
Ну вот решил сделать и на Python.
Код:
# Стек можно сделать через список, но вот нашёл ...
from collections import deque

# Словарь скобок и присвоенных им значений
D = {'(': 1,
     ')':-1,
     '[': 2,
     ']':-2,
     '{': 3,
     '}':-3}

# Анализируемая строка
s = '({f+7*[a**2]})'

myStack = deque()               # Создаём пустой стек
bError = False                  # Ошибки нет
for i in s:
    if bError:                  # Обнаружена ошибка
        break
    if not (i in D):            # Символа нет в словаре
        continue
    elif D[i] > 0:              # Положительные значения
        myStack.append(D[i])    # Добавим значение в стек
    else:                       # Отрицательные значения анализируем
        bError = True           # Пусть стек пуст - это будет ошибка
        if len(myStack):        # Стек не пуст
            bError = myStack.pop() != -D[i] # Сравним значение с вершины стека
                                              # со значением для текущей скобки
                                              # Не равны - True, иначе - False
print((not bError) and len(myStack) == 0) # Результат
Решение основано на работе стека.
Открывающиеся скобки отправляем в стек, а закрывающиеся сравниваем со значением, которое выбирается с вершины стека.

Предполагается, что анализируются скобки, которые занесены в словарь.
Если в строке встречаются другие символы, то они пропускаются.
Как-то так, ...
ViktorR вне форума Ответить с цитированием
Старый 09.02.2022, 23:45   #6
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Цитата:
Сообщение от corpselles Посмотреть сообщение
закидывая саму строку в список для удобства работы с ее элементами через доступ в позиции [0] и [1]
Ну сам алгоритм обсудили выше (для вашего случая и для общего случая). Именно по вашему коду. Строка отлично индексируется и сама - test_string[0]. "[middle1] in ls" это не обращение к позиции, а проверка, что список, состоящий из одного числа middle1, присутствует в списке ls.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Прошу помощь в нахождении ошибки Titanix652 Помощь студентам 0 30.04.2017 21:56
Задача о нахождении простых чисел в матрице alexamazzing Помощь студентам 1 26.10.2012 02:11
Нужна помошь в нахождении ошибки DeIVIiurg Общие вопросы Delphi 0 07.05.2012 17:31
Ошибки в функциях ввода-вывода (Си) spirit_trapper Помощь студентам 2 28.12.2009 12:54
Помощь в классах и функциях. Serror Общие вопросы C/C++ 11 10.10.2009 06:23