Страницы

Поиск по вопросам

суббота, 28 декабря 2019 г.

Вернуть true если скобки совпадают

#javascript


Помогите с примером: необходимо вернуть true если скобки совпадают, или false если
нет. Набор скобок такой: ()[]{}

Например text with([brackets]) true 
text with ([wrong brackets)] false
    


Ответы

Ответ 1



Ну как-то так: /** * Проверяем корректный порядок скобок в строке * * @param {String} exp Строка с скобками для проверки * * @return {Boolean} */ function test(exp){ // Если передали не строку - выходим if(typeof exp !== 'string') return false; let stack = [], // Сюда можно добавлять свои скобки: ключ - открываемая, значение - закрываемая brackets = {'(': ')', '{': '}', '[': ']'}, openRegExp = [], closeRegExp = [], str = exp; // Создаём регулярные выражения для поиска Object.keys(brackets).forEach(e => openRegExp.push(`\\${e}`)); openRegExp = new RegExp(openRegExp.join('|')); for(let i in brackets) if(brackets.hasOwnProperty(i)) closeRegExp.push(`\\${brackets[i]}`); closeRegExp = new RegExp(closeRegExp.join('|')); // Добавляем все найденные открывающие скобки в стёк while((tmp = openRegExp.exec(str)) && (str = str.substr(++tmp.index))) stack.push(tmp[0]); str = exp; // Если нашли какую-то закрывающую скобку while((tmp = closeRegExp.exec(str)) && (str = str.substr(++tmp.index))) // То проверяем: Или закончился стёк, а закрывающие скобки всё прибывают // Или является ли найденная скобка парой к открывающей скобке в конце стёка (самой глубокой) if(!stack.length || brackets[stack.pop()] !== tmp[0]) return false; // Всё ОК return true; } [ `text with([brackets]) true`, `text with ([wrong brackets)] false`, `()[]{}()sdgsdg(sdg((((sg))))))(([[{sds}]]))` ].forEach(t => console.info(t, test(t)));

Ответ 2



Несмотря на то, что ответ уже дан (и помечен как правильный) существует намного более простой и эффективный (с точки зрения вычислительных ресурсов) способ решения задачи. (Это особенно важно, если речь идет о собеседовании.) Суть его заключается в обходе строки и поиске "несбалансированных" скобок с использованием стека. Алгоритм имеет вид: Выбираем первый символ строки Если это открывающая скобка - помещаем ее в стек Если это закрывающая скобка, извлекаем последнее значение из стека и проверяем скобки на соответствие. Если стек пуст или закрывающая скобка не соответствует открывающей - прерываем выполнение и возвращаем false Переходим к следующему символу строки и повторяем действия с п.2 Если по окончании выполнения алгоритма стек не пуст (это возможно, если открывающих скобок больше, чем закрывающих) - возвращаем false. Реализация на JavaScript может иметь вид: var test = function(str) { var chars = str.split(''), stack = [], open = ['{', '(', '['], close = ['}', ')', ']'], closeIndex, openIndex; // Проходимся по строке, проверяя каждый ее символ (п.4). for (var i = 0, len = chars.length; i < len; i++) { openIndex = open.indexOf(chars[i]); if (openIndex !== -1) { // Нашли открывающую скобку. Помещаем ее в стек (п.2). stack.push(openIndex); continue; } closeIndex = close.indexOf(chars[i]); if (closeIndex !== -1) { // Нашли закрывающую скобку. Проверяем ее соответствие открывающей (п.3). openIndex = stack.pop(); if (closeIndex !== openIndex) { return false; } } } // Проверяем дисбаланс открытых/закрытых скобок (п.5). if (stack.length !== 0) { return false; } return true; } Проверить этот код можно вот на таких примерах: console.log(test('text with([brackets])')); // true console.log(test('text with ([wrong brackets)]')); // false console.log(test('text with [wrong brackets')); // false А вот и рабочий пример на JSFiddle.

Ответ 3



Попробовал сам, вот что получилось: var input = document.querySelector('#input'), output = document.querySelector('#output'); input.addEventListener('keydown', update); input.addEventListener('keyup', update); input.addEventListener('change', update); function update () { var errorMessage; try { balanced.matches({source: input.value, open: ['{', '(', '['], close: ['}', ')', ']'], balance: true, exceptions: true}); } catch (error) { errorMessage = error.message; } input.style.border = '10px solid ' + (errorMessage ? 'red' : 'green'); output.innerHTML = errorMessage || ''; } update(); body { background: #333; font-family: arial; } #input { outline: none; } #output { color: grey; }



Комментариев нет:

Отправить комментарий