Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
4 / 4 / 1
Регистрация: 06.10.2020
Сообщений: 128

Проверить строку на сбалансированность скобок

16.11.2022, 21:05. Показов 1486. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день. Есть свой разработанный стек на основе однонаправленного списка. И есть фция, которая определяет, сбалансирована ли строка или нет. Если использовать стандартный стек, то все работает, а если мой, то нет. В чем может быть причина?

STACKLIST.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#pragma once
#include <iostream>
#include <fstream>
#include <functional>
#include <string>
#define _CRTDBG_MAP_ALLOC//проверка корректности данных
#include <crtdbg.h>
#define DBG_NEW new(_NORMAL_BLOCK,__FILE__,__LINE__)
#define newDBG_NEW
 
 
template <typename TInfo>
struct NODE
{
    TInfo info;
    NODE* next;
    NODE(TInfo info, NODE* ptr = nullptr) :info(info), next(ptr) {}
    ~NODE()
    {
        next = nullptr;
    }
};
 
template <typename TInfo>
class STACKLIST
{
using ptrNODE = NODE<TInfo>*;
private:
    ptrNODE head;
public:
    STACKLIST()
    {
        head = NULL;
    }
    ~STACKLIST()
    {
        while (!empty())
            pop();
    }
    TInfo top()
    {
        if (!empty())
            return head->info;
    }
    bool empty()
    {
        return head;
    }
    void push(TInfo elem) {
        ptrNODE p = new NODE<TInfo>(elem, head);
        head = p;
    }
    void pop() {
        ptrNODE node;
        if (!head == NULL)
        {
            node = head;
            head = head->next;
            delete node;
        }
    }
    void print() {
        if (empty())
            std::cout << "Список пуст!\n";
        else
        {
            ptrNODE p = head;
            while (p)
            {
                std::cout << p->info << ' ';
                p = p->next;
            }
            std::cout << '\n';
        }
    }
};
Source.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include "STACKARR.h"
#include "STACKLIST.h"
#include <sstream>
using namespace std;
 
 
bool is_correct(const std::string& str)
{
    STACKLIST<char> stack;
 
    for (int i = 0; i < (int)str.length(); ++i)
    {
        if (str[i] == '(' || str[i] == '{' || str[i] == '[')
        {
            stack.push(str[i]);
        }
        else if (str[i] == ')' || str[i] == '}' || str[i] == ']')
        {
            if
                (
                    !stack.empty()
                    || ((str[i] == ')') ^ (stack.top() == '('))
                    || ((str[i] == '}') ^ (stack.top() == '{'))
                    || ((str[i] == ']') ^ (stack.top() == '['))
                    )
            {
                return false;
            }
 
            stack.pop();
        }
    }
 
    return stack.empty();
}
 
int main()
{
    setlocale(LC_ALL, "Russian");
    std::string str;
    std::cin >> str;
 
    std::cout << (is_correct(str) ? "Yes" : "No") << std::endl;
    return 0;
}
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
16.11.2022, 21:05
Ответы с готовыми решениями:

Проверить бинарное дерево на сбалансированность
Здравствуйте, помогите пожалуйста исправить ошибку в коде. Нужно проверить дерево на сбалансированность. Не на все данные выдает правильный...

Проверить сбалансированность скобок
дано математическое выражение содержащий только круглые дужки.Використовуючы стек проверить сбалансированность скобок.:scratch:

Проверить сбалансированность скобок в тексте
Проверить сбалансированность скобок в тексте(скобки сбалансированы,если закрывающая скобка расположена после соответствующей открывающей и...

15
Злостный нарушитель
 Аватар для Verevkin
10304 / 5726 / 1269
Регистрация: 12.03.2015
Сообщений: 26,531
16.11.2022, 21:13
Цитата Сообщение от Putean Посмотреть сообщение
Если использовать стандартный стек, то все работает, а если мой, то нет. В чем может быть причина?
Сам-то как думаешь?
-----
Попробуй вариант попроще:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// проверка правильной расстановки скобок в строке s
#define push(sp, value)  (*sp++ = (value))
#define pop(sp) (*--sp)
 
bool check_brackets(char* s)
{
  unsigned len = strlen(s);
  if (!len) return true;
  
  char *stack = new char[len], *sp = stack; 
  bool error = false;
  
  for (; !error && *s; s++)  
    switch (*s)
    {
      case '(': push(sp, ')'); break;
      case '[': push(sp, ']'); break;
      case '{': push(sp, '}'); break;
      case ')':
      case ']': 
      case '}': error = (sp == stack) || (pop(sp) != *s);
    } 
  
  error |= sp != stack;
  delete []stack; 
  return !error; 
}
1
4 / 4 / 1
Регистрация: 06.10.2020
Сообщений: 128
16.11.2022, 21:15  [ТС]
Verevkin, нужно именно на стеке на основе списка сделать. Я и спрашиваю, что я сделал не так у себя.
0
Злостный нарушитель
 Аватар для Verevkin
10304 / 5726 / 1269
Регистрация: 12.03.2015
Сообщений: 26,531
16.11.2022, 21:21
Цитата Сообщение от Putean Посмотреть сообщение
Я и спрашиваю, что я сделал не так у себя.
Такие вопросы надо решать в дебаггере - сэкономишь 99% времени.
Попробуй.
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
16.11.2022, 21:21
Библиотечный стек + ваш код = успех.
Ваш стек + ваш код = фейл.
Решаем второе уравнение, приняв что второе слагаемое и результат - верные.
???
0
4 / 4 / 1
Регистрация: 06.10.2020
Сообщений: 128
16.11.2022, 21:22  [ТС]
SmallEvil, я это понимаю и спрашиваю, что у меня не так.
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
16.11.2022, 21:27
Есть предположение :
в попе нет пометки удаляемого указателя в nullptr, что он свободен
то есть ваш список никогда не пуст

Добавлено через 51 секунду
Хотя нет, отменяется, нужно все внимательно обыскать.

Добавлено через 1 минуту
Попробуйте такое извлечение элемента
C++
1
2
3
4
5
6
7
8
9
    void pop() {
        ptrNODE node;
        if (head)
        {
            node = head;
            head = head->next;
            delete node;
        }
    }
0
4 / 4 / 1
Регистрация: 06.10.2020
Сообщений: 128
16.11.2022, 21:28  [ТС]
SmallEvil, Все равно при вводе "(" пишет, что сбалансировано
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
16.11.2022, 21:31
Лучший ответ Сообщение было отмечено Putean как решение

Решение

Цитата Сообщение от Putean Посмотреть сообщение
TInfo top()
    {
        if (!empty())
            return head->info;
    }
        if (!empty()) - это не поможет

Добавлено через 2 минуты
Цитата Сообщение от Putean Посмотреть сообщение
bool empty()
    {
        return head;
    }
        return head==NULL;
0
4 / 4 / 1
Регистрация: 06.10.2020
Сообщений: 128
16.11.2022, 21:32  [ТС]
SmallEvil, Спасибо, сработало
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
16.11.2022, 21:33
То есть, у вас наоборот, если стек полный, то возвращает труе - пустой.
И если станет пустым, выдаст труе - есть элементы.
0
4 / 4 / 1
Регистрация: 06.10.2020
Сообщений: 128
16.11.2022, 21:33  [ТС]
Цитата Сообщение от Putean Посмотреть сообщение
if
                (
                    !stack.empty()
                    || ((str[i] == ')') ^ (stack.top() == '('))
                    || ((str[i] == '}') ^ (stack.top() == '{'))
                    || ((str[i] == ']') ^ (stack.top() == '['))
                    )
            {
Здесь еще !stack.empty() нужно поменять на stack.empty()
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
16.11.2022, 21:36
Хотел сказать про top(), не нужно там проверки на пустоту стека,
что к доступу к неисправному указателю UB будет, что отсутствие возврата значения из функции UB

Добавлено через 1 минуту
Цитата Сообщение от Putean Посмотреть сообщение
Здесь еще !stack.empty() нужно поменять на stack.empty()
Зачем, если работало с библиотечным стеком то все норм.
Я не знаю вашего алгоритма проверки парности скобок. Так что ХЗ.
0
4 / 4 / 1
Регистрация: 06.10.2020
Сообщений: 128
16.11.2022, 21:38  [ТС]
SmallEvil, сам добавил случайно
0
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
17.11.2022, 00:00
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <iostream>
#include <stdexcept>
 
template <typename T> // сократил имя параметра типа
struct Node { // имя класса больше не орёт
    T value; // более семантически значимое имя
    Node* next;
    Node(T value, Node* ptr = nullptr) : value(value), next(ptr) {}
    // деструктор не нужОн
};
 
template <typename T> // сократил имя параметра типа
class LinkedListStack { // переименовал в семантически более значимое имя и оно больше не кричит на меня
    // using ptrNODE = Node<T>*; // избавился, это не нужно
public:
    LinkedListStack() : head(nullptr) {} // инициализация переехала в блок инициализации, используется типизированный nullptr
 
    // Добавлены конструктор копирования
    LinkedListStack<T> &operator=(const LinkedListStack<T> &) = delete;
    // и оператор присваивания
    LinkedListStack(const LinkedListStack<T> &) = delete;
 
    ~LinkedListStack() {
        while (!empty()) {
            pop();
        }
    }
 
    const T &top() const { // исправлена сигнатура на константный метод, возвращающий константную ссылку
        // убран if -- с ним возвращается бред, добавлено исключение
        if (empty()) {
            throw std::underflow_error("stack is empty");
        }
        return head->value;
    }
    bool empty() const { // сигнатура теперь константного метода
        return head == nullptr; // исправлена проверка на пустоту
    }
    // параметр исправлен с передачи по значению на передачу по константной ссылке
    void push(const T &value) {
        head = new Node<T>(value, head); // так короче
    }
    void pop() {
        // добавлено исключение в случае извлечения из пустого стека
        if (empty()) {
            throw std::underflow_error("stack is empty");
        }
        // убрана проверка на null и временная переменная объявляется и назначается в одной строке
        Node<T> *tmp = head;
        head = head->next;
        delete tmp;
    }
 
    // метод print заменён для удобства на оператор вывода в поток
    friend std::ostream &operator<<(std::ostream &out, const LinkedListStack<T> &stack) {
        // убрал вывод сообщения "список пуст!"
        // и сделал вывод в цикле for, так существенно короче
        for (Node<T> *i = stack.head; i != nullptr; i = i->next) {
            out << i->value << ' ';
        }
        return out;
    }
 
private: // блок private переехал в конец класса, так привычнее
    Node<T> *head; // заменил именованный тип на действительный
};
 
// имена поменяны на более семантически близкие мне
bool isCorrect(const std::string &value) {
    LinkedListStack<char> stack;
    for (char c : value) { // краткая форма прохода по итерируемым объектам
        // if перешел в case, поменяны местами случаи открывающих и закрывающих скобок -- так короче
        switch (c) {
            case '(': stack.push(')'); break;
            case '[': stack.push(']'); break;
            case '{': stack.push('}'); break;
            case ')':
            case ']':
            case '}':
                // если стек пуст или зкрывающая скобка не та
                if (stack.empty() || stack.top() != c) {
                    return false; // некорректная расстановка скобок
                }
                stack.pop();
                break;
        }
    }
    return stack.empty(); // расстановка скобок корректа только если по завершению стек пустой
}
 
int main() {
    std::string str;
    std::cin >> str;
 
    std::cout << (isCorrect(str) ? "Yes" : "No") << std::endl;
    return 0;
}
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12937 / 6804 / 1821
Регистрация: 18.10.2014
Сообщений: 17,217
17.11.2022, 00:56
Цитата Сообщение от Putean Посмотреть сообщение
сли использовать стандартный стек, то все работает, а если мой, то нет. В чем может быть причина?
В вашем кривом стеке, очевидно.

Цитата Сообщение от Putean Посмотреть сообщение
if (!head == NULL)
Что это за условие в if? Что оно проверяет?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
17.11.2022, 00:56
Помогаю со студенческими работами здесь

Проверить сбалансированность скобок в строке
• Дана строка S. проверить сбалансированность скобок.

Проверить строки на сбалансированность скобок
Добрый день. Есть свой разработанный стек на основе однонаправленного списка. И есть фция, которая определяет, сбалансирована ли строка или...

Проверить сбалансированность скобок в тексте
Помогите плиз. Нужно сдать зачёт 24 июня((( 1) Из текстового файла А сформировать текстовый файл В, в который включать только нечётные...

Проверить сбалансированность скобок в заданном тексте
Задан текст, в котором есть круглые скобки. Разработать программу, которая проверяет сбалансированность скобок в заданном тексте. Если...

Проверить сбалансированность скобок в математическом выражении с помощью цепочечных команд
Добрый вечер! Помогите, пожалуйста, с кодом. Есть наметки, но как его реализовать, чтобы всё правильно выводило на экран, даже не...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru