在Ruby中编写“匹配平衡括号”程序的更好方法

时间:2014-03-02 00:12:05

标签: ruby if-statement conditional-statements

这个方法应该接受一个字符串,并检测括号'(''''''''在字符串中是否与对应的(相反)括号正确关闭。

首先,是否有更优雅,更紧凑的方式来编写此位而不使用所有“或”s(||):

            split_array.each do |i| 
              if (i == "{" || i == "(" || i == "[")
                  left.push(i)
                else (i == "}" || i == ")" || i == "]")
                  right.push(i)
                end
             end

我的第二个问题是,这段代码是否可怕(见下文)?看来我应该能够用更少的线来写这个,但从逻辑上讲,我还没有提出另一个解决方案(还是。) 该代码适用于大多数测试,但它为此测试返回false(请参阅底部的所有驱动程序测试):p valid_string?(“[(text){}]”)== true

任何批评都将不胜感激! (另外,如果有更好的部分发布,请告诉我) 谢谢!

def valid_string?(string)

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

        left = Array.new
        right = Array.new
        return_val = true

        split_array = string.split(//)
        split_array.delete_if { |e| e.match(/\s/) }

          split_array.each do |i| 
          if (i == "{" || i == "(" || i == "[")
              left.push(i)
            else (i == "}" || i == ")" || i == "]")
              right.push(i)
            end
          end

        # p left
        # p right

        left.each_index do |i|
          if left[i] != opposites[right[i]]
              return_val = false
          end
        end  
        return_val
    end 

    p valid_string?("[ ] } ]") == false
    p valid_string?("[ ]") == true
    p valid_string?("[  ") == false                 
    p valid_string?("[ ( text ) {} ]") == true    
    p valid_string?("[ ( text { ) } ]") == false  
    p valid_string?("[ (] {}") == false 
    p valid_string?("[ ( ) ") == false

------- 更新:在尝试了一些不同的方法之后,我的重构就是: -----------

def valid_string?(str)

    mirrored = { "[" => "]", "{" => "}", "(" => ")" }
    open_brackets = Array.new

    split_str_array = str.split("")

    split_str_array.each do |bracket| 
      if bracket.match(/[\[|\{|\(]/) then open_brackets.push(bracket)
      elsif bracket.match(/[\]|\}|\)]/)
        return false if mirrored[open_brackets.pop] != bracket
      end
    end
    open_brackets.empty?
end 

8 个答案:

答案 0 :(得分:3)

我的方法如下:

def valid_string?(string)
  open_paren = ['[','{','(']
  close_paren = [']','}',')']
  open_close_hash = {"]"=>"[", "}"=>"{", ")"=>"("}
  stack = []
  regex = Regexp.union(close_paren+open_paren)
  string.scan(regex).each do |char|
    if open_paren.include? char
      stack.push(char)
    elsif close_paren.include? char
      pop_val = stack.pop
      return false if pop_val != open_close_hash[char]
    end
  end
  open_paren.none? { |paren| stack.include? paren }
end 

valid_string?("[ ] } ]") # => false
valid_string?("[ ]") # => true
valid_string?("[  ") # => false
valid_string?("[ (] {}") # => false
valid_string?("[ ( ) ") # => false
valid_string?("[ ( text { ) } ]") # => false
valid_string?("[ ( text ) {} ]") # => true

Algorithm :

  1. 声明字符堆栈S
  2. 现在遍历表达式字符串exp。
    • 如果当前字符是起始括号(‘(‘‘{‘‘['),则将其推送到堆栈。
    • 如果当前字符是右括号(')''}'']'),则从堆栈弹出,如果弹出的字符是匹配的起始括号,那么罚款其他括号不是平衡的。
  3. 完成遍历后,如果剩下一些起始支架 然后堆叠“not balanced”

答案 1 :(得分:2)

最短的正则表达式解决方案可能是:

def valid_string? orig
  str = orig.dup
  re = /\([^\[\](){}]*\)|\[[^\[\](){}]*\]|\{[^\[\](){}]*\}/
  str[re] = '' while str[re]
  !str[/[\[\](){}]/]
end

答案 2 :(得分:0)

这应该提供相同的功能

def valid_string?(string)
  #assume validity
  @valid = true
  #empty array will be populated inside the loop
  @open_characters = []
  #set up a hash to translate the open character to a closing character
  translate_open_closed = {"{" => "}","["=>"]","("=>")"}
  #create an array from the string loop through each item 
  string.split('').each do |e| 
    #adding it to the open_characters array if it is an opening character
    @open_characters << e if e=~ /[\[\{\(]/
    #if it is a closing character then translate the last open_character to 
    #a closing character and compare them to make sure characters are closed in order
    #the result of this comparison is applied to the valid variable
    @valid &= e ==  translate_open_closed[@open_characters.pop] if e=~ /[\]\}\)]/
  end
  #return validity and make sure all open characters have been matched
  @valid &= @open_characters.empty?
end

您也可以使用注入执行此操作,但它的透明度会低一些。

答案 3 :(得分:0)

另一种方式:

s = str.gsub(/[^\{\}\[\]\(\)]/, '')
while s.gsub!(/\{\}|\[\]|\(\)/, ''); end
s.empty?

Ex 1
str = "(a ()bb [cc{cb (vv) x} c ]ss) "
s = str.gsub(/[^\{\}\[\]\(\)]/, '') #=> "(()[{()}])"
while s.gsub!(/\{\}|\[\]|\(\)/, '') do; end
  s => "([{}])" => "([])" => "()" => "" gsub!() => nil
s.empty? #=> true

Ex 2
str = "(a ()bb [cc{cb (vv) x] c }ss) "
s = str.gsub(/[^\{\}\[\]\(\)]/, '')  #=> "(()[{()]})"
while s.gsub!(/\{\}|\[\]|\(\)/, '') do; end
  s => "([{]})" gsub!() => nil 
s.empty? #=> false

答案 4 :(得分:0)

我被赋予了这个模拟面试编码挑战的一部分。就我而言,(def my-map {:a "A" :b "B" :c 3 :d 4}) (let [{a :a, x :x, :or {x "Not found!"}, :as all} my-map] (println "I got" a "from" all) (println "Where is x?" x)) ;= I got A from {:a "A" :b "B" :c 3 :d 4} ;= Where is x? Not found! 中还传递了一个parens地图,这意味着括号的类型可能会有所不同。

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

答案 5 :(得分:0)

怎么样:

#require 'watir-webdriver'
require 'watir'

caps = Selenium::WebDriver::Remote::Capabilities.firefox
caps['acceptInsecureCerts'] = true
driver = Selenium::WebDriver.for(:firefox, desired_capabilities: caps)
browser = Watir::Browser.new(driver)

# text to show on console
puts "Beginning of the automation of IRCTC webpage"

browser.goto("https://www.irctc.co.in/eticketing/loginHome.jsf")

#browser.button(:id, "returnButton").click

#set a variable
search_text = "my_username"

#puts " Step 2: enter "+ search_text +" in the search text field."
browser.text_field(:name, "j_username").set search_text # "j_username" is the name of the search field

#browser.span(:class, "RveJvd snByac").click # "RveJvd snByac" is the class-name of the Search button

search_text = "my_password"
browser.text_field(:name, "j_password").set search_text

#Here I need to enter CAPTCHA before proceeding to next syntax.

browser.button(:type, "submit").click

答案 6 :(得分:0)

def valid_string?(exp)
  return false if exp.size % 2 != 0
  curly = "{}"
  square = "[]"
  parenthesis = "()"
  emptystr = ""
  loop do 
   old_exp = exp
   exp = exp.sub(curly, emptystr)
   break if exp == emptystr
   exp = exp.sub(square, emptystr)
   break if exp == emptystr
   exp = exp.sub(parenthesis, emptystr)
   break if exp == emptystr || exp == old_exp
 end
 exp == emptystr
end

答案 7 :(得分:0)

你可以试试这个方法:

def balanced_brackets?(string)
  # your code here
  stack = []
  opening_bracket = ['{','[', '(']
  closing_bracket = ['}', ']', ')']
  string.chars.each do |char|
    if opening_bracket.include?(char)
      stack << char
    elsif closing_bracket.include?(char)
      value = stack.pop
      return false if opening_bracket.index(value) != closing_bracket.index(char)
    end
  end
  
  stack.empty?
end

如果您想了解伪代码,请尝试 coursera 中的此链接(从 0:56 开始)。