2013-12-23 8 views
9

メソッド 'valid_string?'を書きます。文字列を受け入れる。大括弧、かっこ、中括弧が正しく閉じると、真を返します。それ以外の場合はfalseを返します。Rubyで閉じ括弧、カッコまたは括弧の妥当性をチェックする方法

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

私のコードは:すべてのためにfalseを返しています。個々のケースに明示的なブーリアンを使ってみました{} || ()||など、動作しませんでした。どちらも、すべてに対して真か偽かを返します。それは私の運転免許証ですか?

def valid_string?(str) 

    if str == ("\[\s+]") 
     true 
    else 
     false 
    end 
end 

更新された解決策:---------------------------------------- -------- はい! #matchは間違いなく改善されました!テストコードの私の最後の行は真であると評価されていますが。それが偽であるべきとき。 。 。

def valid_string?(str) 
if str.match "(\\[.+\\])" || "|(\\(\\))" || "|({})" 
    return true 
else 
    return false 
    end 
end 

puts valid_string?("[ ]")     # returns true 
puts valid_string?("[ ")     # returns false 
puts valid_string?("[ (text) {} ]")  # returns true 
puts valid_string?("[ (text {) } ]")  # returns false 
+0

'=='は 'regex == regex'を比較するために使用され、' regex == string'は比較されません。 '〜='や 'match'を使いたいとします。 [docs](http://www.ruby-doc.org/core-2.0.0/Regexp.html#method-i-3D-3D) –

+1

正規表現を使って注文を確認することはできませんあなたはデータのLIFO構造を使用しなければなりません。 – rullof

+1

これは、正規表現で実行するチェックの種類ではありません。 –

答えて

8

この問題を解決するにはregexを使用するのが煩雑かもしれないと思います。潜在的な解決策は次のとおりです。スタックを使用して、横方向に{[(のような左のシンボルを記録することができます。あなたが右のシンボルに会うたびに、スタックトップのシンボルがこの右のシンボルと一致するかどうかをチェックするだけです。一致しない場合は、falseを返すだけです。以下は

が私のコードです:

def valid_string?(str) 
    stack = [] 
    symbols = { '{' => '}', '[' => ']', '(' => ')' } 
    str.each_char do |c| 
    stack << c if symbols.key?(c) 
    return false if symbols.key(c) && symbols.key(c) != stack.pop 
    end 
    stack.empty? 
end 

puts valid_string?('[ ]')     # returns true 
puts valid_string?('[ ')     # returns false 
puts valid_string?('[ (text) {} ]')  # returns true 
puts valid_string?('[ (text {) } ]')  # returns false 
+0

これは、必要な条件です。 – sawa

+0

だから、ある文字列が私が言及したアルゴリズムを渡すことがあるかもしれないが、まだ無効な文字列である場合があるということですか?あなたは私に例を教えてもらえますか? – WDan

+0

OPの2番目の例を見てください。 – sawa

5

はここで正規表現を使用しない方法です:

def valid_string?(str) 
    strim = str.gsub(/[^\[\]\(\)\{\}]/,'') 
    return true if strim.empty? 
    return false if strim.size.odd? 
    loop do 
    s = strim.gsub('()','').gsub('[]','').gsub('{}','') 
    return true if s.empty? 
    return false if s == strim 
    strim = s 
    end 
end 

p valid_string?("[ ]")    # => true 
p valid_string?("[ ")    # => false 
p valid_string?("[ (text) {} ]") # => true 
p valid_string?("[ (text {) } ]") # => false 
p valid_string?("[ (text { more text { (more text) }})]") # => true 
  • まず(」中以外のすべての文字を削除)[] {} "
  • 残りの文字列が空の場合はtrueを返します。
  • 残りの文字列に奇数個の文字が含まれている場合はfalseを返します。
  • 文字列が空になるまで、隣接するペア '()'、 '[]'および '[]'を削除し続けます。この場合はtrueを返します。その場合はfalseを返します。
+0

私はこれがとても気に入りました。 – Donovan

+0

あなたは私を赤面にする@Donovan。 –

+0

@Cary Swovelandああうわー!なんと美しい!私はこれが本当に良い解決策だと思います。何らかの理由で私はこの問題をあまりにも単純に見ていました。しかし、それは私が元々想定していたよりも少し創造性を必要とするようです。ありがとうございました! – user3130116

1

単純なカウントルーチンはどうですか?

def valid_string?(str) 
    match_count = 0 

    str.each_char do |c| 
    match_count += 1 if [ '[', '{', '(' ].include?(c) 
    match_count -= 1 if [ ']', '}', ')' ].include?(c) 
    end 

    return match_count == 0 
end 
+0

これは最後のテスト条件と一致しないことに気がつきましたが、複雑なものを必要としない人のために答えを残します。 – Donovan

+0

この回答を適用することができます。 (ただし、 'match_point'はいつも厳密に正のままである、つまりループ内にあることを確認する必要があります)。この回答の問題は、現在、すべての括弧文字を同じものとして扱うことです。しかし、それを修正するには、パラメータとして、開始と終了の括弧文字、そして 'valid_string?'の 'valid_for( '('、 ')'、str)&& valid_for( '{' '}'、str)&& valid_for( '['、 ']'、str) '(ここで' valid_for'はその補助メソッドです)。 – amnn

+0

@Donovanありがとう!私はasQuirrelの補助的な方法でこれを試してみるつもりだと思う。 – user3130116

5

それは楽しいだったという理由だけで、私は、Rubyの道を先に行って、このを解決:)

class Brackets 
    class Bracket 
    def initialize(open, close) 
     @open = open 
     @close = close 
     @match_count = 0 
    end 
    attr_reader :match_count, :open, :close 

    def check(c) 
     @match_count += 1 if c == @open 
     @match_count -= 1 if c == @close 
    end 
    end 

    def initialize 
    @brackets = [] 
    @stack = [] 
    @valid = true 
    end 

    def add(open, close) 
    @brackets << Bracket.new(open,close) 
    end 

    def check(c) 
    @brackets.each do |b| 
     b.check(c) 
     @stack.push(c) if c == b.open 
     @valid = false if c == b.close and @stack.pop != b.open 
    end 
    end 

    def valid? 
    total = 0 
    @brackets.each { |b| total += b.match_count } 
    total == 0 && @valid == true 
    end 
end 

def valid_string?(str) 
    brackets = Brackets.new 
    brackets.add('[', ']') 
    brackets.add('{', '}') 
    brackets.add('(', ')') 

    str.each_char { |c| brackets.check(c) } 
    brackets.valid? 
end 

# Our tests 
puts valid_string?("[ ]") ? 'true' : 'false'     # returns true 
puts valid_string?("[ ") ? 'true' : 'false'     # returns false 
puts valid_string?("[ (text) {} ]") ? 'true' : 'false'  # returns true 
puts valid_string?("[ (text {) } ]") ? 'true' : 'false' # returns false 
puts valid_string?("[ (text { }) ]") ? 'true' : 'false' # returns true 
1

私はこのような状況で本当にうまく動作するように再帰を見つけました。お役に立てれば!

def valid_string?(string) 
    bracket_string = string.gsub(/[^\[\]\(\)\{\}]/,'').gsub('()','').gsub('[]','').gsub('{}','') 
    return true if bracket_string.empty? 
    return false if bracket_string.length.odd? 
    return false if bracket_string.include?(string) 
    valid_string?(bracket_string) 
end 
関連する問題