在红宝石中使用树状结构进行支架匹配

时间:2017-07-29 23:46:41

标签: ruby binary-tree brackets

给定一个只包含集合{}[]()中的字符的字符串我想生成一个以开括号开头的树结构 - {[( - 如果下一个字符是另一个字符,则添加一个节点开口支架。如果下一个字符是与当前节点值匹配的右括号,我希望删除当前节点。如果下一个字符是与当前节点不匹配的右括号,则它应该返回错误。 例如,给定字符串"{[()]}",代码将执行以下操作:

    {
   /
  [
 /
(

然后下一个字符是与当前(最近插入的)节点匹配的右括号,因此它应该删除该节点。

    {
   /
  [

然后

{

最后

nil

以下代码几乎可以正常工作,但由于它从上到下遍历树,它将匹配在它们之间具有未闭合括号的括号,例如“{[(]}”。我跟踪高度b / c我觉得我应该能够使用它来跳转到最后一个节点,但不知道如何。

module BracketTree
  class Node
    attr_accessor :key, :left, :right

    BRACKETS = {"{" => "}",
                "[" => "]",
                "(" => ")"
                }

    def initialize(key)
      @key = key
      @left = nil
      @right = nil
    end

    def height
      @height = 1
      left = @left
      while !left.nil?
        left = left.left
        @height += 1
      end
      @height
    end

    def insert(new_key)
      if @key.nil?
        @key = new_key
      elsif BRACKETS[new_key]
        if @left.nil?
          @left = Node.new(new_key)
        else
          @left.insert(new_key)
        end
      elsif @left.nil? && BRACKETS[@key] == new_key
        @key = nil
      elsif BRACKETS[@left.key] == new_key
        @left = nil
      else
        left = @left
        while !left.nil?
          if BRACKETS[left.key] == new_key
            left.key = nil
            break
          else
            left = left.left
          end
        end
        if left.nil?
          raise "unmatched bracket or non bracket char"
        else
          left.right
        end
      end
    end

  end

end

1 个答案:

答案 0 :(得分:0)

我相信应该在这里使用堆栈。

<强>代码

MATCH_UP = { "}"=>"{", "]"=>"[", ")"=>"(" }
LT_MARKERS = MATCH_UP.values #=> ["{", "[", "("]

def parse_markers(str)
  str.each_char.with_index.with_object([]) do |(marker, i), stack|
    if LT_MARKERS.include?(marker)
      stack << marker
    elsif MATCH_UP[marker] == stack.last
      stack.pop
    else
      return [stack.join, i]
    end
  end.join
end

有三种可能的结果。

  • 如果str具有平衡标记,则该方法返回""
  • 如果str的所有字符相互一致,但在检查完所有字符后堆栈不为空(例如,"(((",将以stack.join #=> "(0(0("终止,{{1返回(表示stack.join不平衡)。
  • 否则返回数组str,其中[stack.join, off]是确定标记不平衡时的堆栈,因为发现字符stack与之不一致堆栈。

<强>实施例

str[off]
相关问题