Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 18.01.2015, 17:34
Интересующийся
Отправить личное сообщение для y0uix Посмотреть профиль Найти все сообщения от y0uix
 
Регистрация: 22.10.2013
Сообщений: 11

Рекурсивная валидация
Здравствуйте!

Стоит задача валидировать вложенные скобки (({[) произвольной глубины вложенности. Причем может быть и так ({})[({})], это также валидный формат.

Написал:
function validBraces(braces) {
  if (braces.length % 2 !== 0) {
    return false;
  }
  
  var assoc = {
    '(': ')',
    '{': '}',
    '[': ']'
  };

  for (var i = 0, m; i < Math.round(braces.length / 2); i += 1) {
    if (!~Object.keys(assoc).indexOf(braces[i])) continue;
    m = braces.match(RegExp('\\' + braces[i] + '(' + (braces[i] === braces[i + 1] ? '.' : '[^\\' + assoc[braces[i]] + ']') + '*)\\' + assoc[braces[i]]));
    if (m === null || m[1].length % 2 !== 0) return false;
  }
  return true;
}

Он корректно мэтчит ({})[({})], но некорректно (({{[[]]}})), причем во многих других случаях также корректно отрабатывает.

Подскажите пожалуйста, где я не прав и как бы вы реализовали задачу? Спасибо.
Ответить с цитированием
  #2 (permalink)  
Старый 18.01.2015, 17:51
Интересующийся
Отправить личное сообщение для y0uix Посмотреть профиль Найти все сообщения от y0uix
 
Регистрация: 22.10.2013
Сообщений: 11

for (var i = 0, m; i < Math.round(braces.length / 2); i += 1)

Math.round тут излишне конечно. Идея собственно в том, чтобы мэтчить крайние символы-пары, а внутренность сперва проверять на четное количество скобок.
Ответить с цитированием
  #3 (permalink)  
Старый 18.01.2015, 18:31
Аватар для danik.js
Профессор
Отправить личное сообщение для danik.js Посмотреть профиль Найти все сообщения от danik.js
 
Регистрация: 11.09.2010
Сообщений: 8,804

Зачем там вообще регулярки - я не пойму? Пройди посимвольно и складывай в стек открывающие скобки, извлекай закрывающие. Если в стеке неподходящего вида скобка - значит ошибка. Если в конце стек не опустел - тоже ошибка.
__________________
В личку только с интересными предложениями
Ответить с цитированием
  #4 (permalink)  
Старый 18.01.2015, 18:52
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,070

y0uix,
Баланс открывающихся и закрывающихся скобок.Стеки в JS
Ответить с цитированием
  #5 (permalink)  
Старый 18.01.2015, 18:53
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 29.11.2011
Сообщений: 3,924

y0uix,

console.log(isValid('({})[({})]'));
console.log(isValid('(({{[[]]}}))'));
console.log(isValid('({})[({})]'));


function isValid(string) {
    var regexp = /(?:\(.*?\)|\[.*?\]|\{.*?\})/;
    var replacementFn = function(line) {
        return line.slice(1, -1);
    };

    while (regexp.test(string)) {
        string = string.replace(regexp, replacementFn);
    }

    return !string.length;
}


Но, на первый взгляд, это не будет корректно работать потому, что надо делать так, как написал danik.js
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук

Последний раз редактировалось nerv_, 18.01.2015 в 18:55.
Ответить с цитированием
  #6 (permalink)  
Старый 18.01.2015, 21:34
Интересующийся
Отправить личное сообщение для y0uix Посмотреть профиль Найти все сообщения от y0uix
 
Регистрация: 22.10.2013
Сообщений: 11

Спасибо всем огромное, самый мощный анклав JS-ниндзя, который я встречал.

Вот два решения:
function validBraces(braces) {
  var assoc = {
    '(': ')',
    '{': '}',
    '[': ']'
  },
  stack = [],
  char,
  len,
  i;

  for (i = 0, len = braces.length; i < len; i += 1) {
    char = braces[i];
    if (assoc[char]) {
      stack.push(char);
    } else {
      if (char !== assoc[stack.pop()]) {
        return false;
      }
    }
  }

  return !stack.length;
}


function validBraces(braces) {
  var pattern = /\(\)|\{\}|\[\]/g;
  while (pattern.test(braces)) {
    braces = braces.replace(pattern, '');
  }
  return !braces.length;
}
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
js рекурсивная функция с for.. in циклом frying Общие вопросы Javascript 6 25.08.2014 10:50
Валидация формы в зависимости от значения radio batton housewm Events/DOM/Window 1 10.01.2014 18:46
Валидация пользователя по IP-адресу lazerru Общие вопросы Javascript 1 03.04.2013 12:40
Повторение скрипта покругу - Валидация lamer Общие вопросы Javascript 14 18.07.2012 21:54
Валидация формы Ваяс Элементы интерфейса 8 11.07.2012 15:20