Проверка правильности расстановки скобок разного типа в строке - Разбор алгоритмической задачи
Primary tabs
Forums:
Задача:
Проверить, правильно ли закрываются скобки ()[]{}
Например:
()[]{} - правильно
([{}[]])() -правильно
({]){} - неправильно
Основная идея
Используем структуру стэка:
- Кладем в стэк открывающие скобки
- Выщёлкиваем из стэка эти открывающие скобки, если нашли соответствующую закрывающую (того же типа)
Ну и дополнительные моменты:
- Для каждой закрывающей скобки в стэке должно что-то быть (совпадение количеств)
- Если мы встретили закрывающую скобку одного типа, а наверху стэка лежит открывающая другого - то это ошибка (завершаем обработку), значит скобки расставлены неправильно
- Если мы прочитали всю строчку, то стэк должен стать пустым - тогда скобки расставлены правильно
Возможная реализация в коде
На примере Golang-а:
package main
import "fmt"
func isValidBrackets(s string) bool {
// Карта соответствия закрывающей скобки открывающей
brackets := map[rune]rune{
')': '(',
']': '[',
'}': '{',
}
// тут будем хранить открывающие скобки
var stack []rune
for _, char := range s {
// Если это закрывающая скобка
if opening, ok := brackets[char]; ok {
// Проверяем: стек не пуст и на вершине подходящая открывающая
if len(stack) > 0 && stack[len(stack)-1] == opening {
stack = stack[:len(stack)-1] // Удаляем из стека (Pop)
} else {
return false // Либо лишняя закрывающая, либо не тот тип
}
// если допустимы иные символы, чтобы проигнорировать их
// проверим перед отправкой в стэк, что это именно
// открывающая скобка
} else if char == '(' || char == '[' || char == '{' {
// Если открывающая — кладем в стек (Push)
stack = append(stack, char)
}
}
// Если стек пуст — все скобки нашли пару
return len(stack) == 0
}
func main() {
// Тестовые случаи
testCases := []string{
"()",
"()[]{}",
"(]",
"([{}])",
"((()))",
"({[}])",
"",
"(((",
")))",
"()[{} ]",
"([)]",
}
for _, test := range testCases {
result := isValidBrackets(test)
fmt.Printf("'%s' -> %t\n", test, result)
}
}
-- range для строки в golang сразу перебирает руны (подходит для юникода)
Анализ сложности
- O(N) - линейная по количеству чтений символов строки, относительно ее длины
- O(N) и по памяти - тоже линейная (относительно размера стэка) - в худщем случае, для строки, состоящей только из открывающих скобок
- Log in to post comments
- 87 reads