循环仅匹配相同的符号类型,而不是根据字符串中的位置进行比较

时间:2013-11-13 01:58:48

标签: ruby regex loops recursion

我们查找了偶数匹配的大括号,但没有考虑数组中的位置。像这样:

def brace_count(brace_array)
    # ["{}[]()", "{}[]()"]

    brace_array.each do |braces|
        brace_chars_array = braces.split('')
        # ["{", "}", "[", "]", "(", ")"]
        paren_count = 0
        brace_count = 0
        bracket_count = 0
        brace_chars_array.each do |char|
            if char == "[" || char == "]"
                bracket_count += 1
            elsif char == "{" || char == "}"
                brace_count += 1
            elsif char == "(" || char == ")"
                paren_count += 1
            end
        # brace_count = 2, paren_count = 2, bracket_count = 2
        if brace_count % 2 == 0 && paren_count  % 2 == 0 && bracket_count % 2 == 0
            puts 1
        else 
            puts 0
        end
    end
end

有谁知道如何处理这个问题?我们无法弄清楚如何递归调用它。我认为正则表达式不是正确的方法。如果大括号匹配则返回1,如果不匹配则返回0,如果两个匹配括号之间有不同类型的大括号,则测试应该生成0

示例:

{{[]}} = 1 
{([[)]]} = 0 (Even though the brackets are all even numbers [1 open 1 close, just not ordered properly])

4 个答案:

答案 0 :(得分:1)

我认为你正在寻找的是一个LIFO堆栈,以便在遇到大括号时跟踪大括号。你可以通过推送和弹出它来获得数组。

如果您只是想验证支架是否平衡,最简单的方法是穿过绳子,在堆叠上粘开开支撑,当您到达关闭支撑时弹出堆叠并验证关闭支撑匹配刚刚弹出的左大括号。当它们不匹配时返回0,如果到达字符串的末尾,如果堆栈为空则返回1,如果不是则返回0。

答案 1 :(得分:0)

为此使用String#count。

input_string.count(string_containing_chars_to_count)

它会大大缩短您的代码:

input = "{}[]()"
brackets, braces, parens = ['[]', '{}', '()'].map { |t| input.count t }     
#=> [2, 2, 2]

但是,作为提示:您希望每次遇到'{'时递增计数器,并在每次遇到'}'时递减计数器,然后在字符串结束时检查计数器是否为0。 我相信你可以从中找到它!

答案 2 :(得分:0)

在您的示例中,您的字符串具有匹配的大括号,括号和圆括号。如果它们总是在字符串中显示为对(例如,不是"[{}]"),则问题会大大简化。

假设您正在处理字符串:

str = "{}[]()"

请注意

str.scan(/../) # => ["{}", "[]", "()"]

所以你可以这样做:

str.strip.scan(/../).each do |s|
  case s
  when "{}"
    ..do something..
  when "[]"
    ..do something..
  when "()"
    ..do something..
  else
    .. raise an error..
  end
end

(我在stripstr之间插入了scan,以便在scan拆分对之前删除可能位于字符串开头或结尾的任何空格。)

使用对的优点是,如果您有不匹配的对,则会标记错误:

str = "{}[[()"

您无需检查以确定[的数量是否与]的数量相同。

答案 3 :(得分:0)

我猜你的老师期待这样的事情:

def brace_match?(chars_array)
  while ['{', '[', '('].include?(chars_array.first)
    opener = chars_array.shift
    return false unless brace_match?(chars_array)  # This is the recursive call (s)he mentioned.
    closer = chars_array.shift
    case opener
    when '['
      return false if closer != ']'
    when '{'
      return false if closer != '}'
    when '('
      return false if closer != ')'
    end
  end
  return chars_array.empty? || ['}', ']', ')'].include?(chars_array.first)
end

def brace_count(brace_array)
    # ["{}[]()", "{}[]()"]

    brace_array.each do |braces|
        brace_chars_array = braces.split('')
        # ["{", "}", "[", "]", "(", ")"]
        if brace_match?(brace_chars_array)
            puts 1
        else
            puts 0
        end
    end
end

这可以做同样的事情,但有点压缩代码:

Braces = { '{' => '}', '[' => ']', '(' => ')' }

def brace_match?(chars_array)
  while Braces.keys.include?(chars_array.first)
    opener = chars_array.shift
    return false unless brace_match?(chars_array)  # This is the recursive call (s)he mentioned.
    return false unless chars_array.shift == Braces[opener]
  end
  return chars_array.empty? || Braces.values.include?(chars_array.first)
end