質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

2回答

1324閲覧

rubyについて質問です。

pocarisweat

総合スコア16

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

1クリップ

投稿2017/06/16 09:07

マル括弧、ナミ括弧、カク括弧から構成される文字列について、
各括弧が正しい入れ子関係になっているかどうかを判定するプログラムを
作りたいです。初心でも分かりやすいコードでお願いしたいです。

ruby初心者なため1行目に何をしていて2行目は何をやっていてなどの
詳しい説明もいただきたいです。。。

正しい入れ子関係の例
[]
[]{}
[()]{}
([()]{})

誤った入れ子関係の例
(]) ... 開いていない角括弧を閉じている
[]( ... 開いた丸括弧を閉じていない
([)] ... 開いた角括弧を閉じる前に丸括弧を閉じてい

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

初心者でも分かりやすいコードにはなっていませんが、コード例と実行例を示します。
syntax.rb

ruby

1# 閉じ括弧文字に対応する開き括弧文字を設定する 2BRACKETS = { 3 ')' => '(', 4 ']' => '[', 5 '}' => '{' 6}.freeze 7 8def check_brakets(str) 9 nest = [] # 括弧のネスト状態を保持する。括弧が閉じたら削除される。 10 poss = [] # 括弧の開始位置を保持する。括弧が閉じたら削除される。 11 12 # 文字列を前から後ろに1文字ずつ処理する。 13 str.each_char.with_index do |c, pos| 14 case c 15 when '(', '[', '{' 16 nest << c 17 poss << pos 18 when ')', ']', '}' 19 mode = nest.pop 20 poss.pop 21 if mode != BRACKETS[c] 22 return { message: "開いていない #{BRACKETS[c]} を閉じている。", pos: pos } if mode.nil? 23 return { message: "#{mode} を閉じる前に #{c} を閉じている。", pos: pos } 24 end 25 end 26 end 27 return { message: "#{nest[-1]} を閉じていない", pos: poss[-1] } unless nest.empty? 28 29 nil 30end 31 32TEST_DATA = [ 33 # 入れ子状態が OK な例 34 '[]', 35 '[]{}', 36 '[()]{}', 37 '([()]{})', 38 '(1+2)*(2+3)', 39 '', 40 41 # 入れ子状態が不正な例 42 '(])', # 開いていない角括弧を閉じている 43 '[](', # 開いた丸括弧を閉じていない 44 '([)]', # 開いた角括弧を閉じる前に丸括弧を閉じている 45 ')', # 開いていない丸括弧を閉じている 46 ')[', # 開いていない丸括弧を閉じている 47 '([]', # 開いた丸括弧を閉じていない 48].freeze 49 50TEST_DATA.each do |str| 51 error = check_brakets(str) 52 if error.nil? 53 puts "#{str} -> OK" 54 else 55 puts "#{str} -> #{error[:message]}" 56 puts "#{' ' * error[:pos]}^" 57 puts 58 end 59end

実行例:

$ ruby syntax.rb [] -> OK []{} -> OK [()]{} -> OK ([()]{}) -> OK (1+2)*(2+3) -> OK -> OK (]) -> ( を閉じる前に ] を閉じている。 ^ []( -> ( を閉じていない ^ ([)] -> [ を閉じる前に ) を閉じている。 ^ ) -> 開いていない ( を閉じている。 ^ )[ -> 開いていない ( を閉じている。 ^ ([] -> ( を閉じていない ^

投稿2017/06/18 13:41

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/06/18 15:30

勉強になります。
guest

0

ベストアンサー

Ruby

1# encoding: utf-8 2 3def check(str) 4 count = str.size 5 6 loop do 7 str = str.gsub(/\(\)|\[\]|\{\}/, '') 8 str.size == count ? break : count = str.size 9 end 10 11 str.size.zero? ? '入れ子です' : '入れ子ではないです' 12end 13 14sample = ['[]', '[]{}', '[()]{}', '([()]{})', '(])', '[](', '([)]'] 15 16sample.each do |e| 17 puts "『#{e}』は#{check(e)}。" 18end

実行結果例

『[]』は入れ子です。 『[]{}』は入れ子です。 『[()]{}』は入れ子です。 『([()]{})』は入れ子です。 『(])』は入れ子ではないです。 『[](』は入れ子ではないです。 『([)]』は入れ子ではないです。

説明付きバージョン

Ruby

1# encoding: utf-8 2 3# 入れ子かどうかの判定をするプログラム。 4# 私のやり方 5# 1.gsubで「かっこ」を削除しまくる。 6# 2.ペアになっていない「かっこ」は残る。 7# 3.文字列の長さが0にならなかったら 8# 「正しい」入れ子になっていない。 9# 0になったら「正しい」入れ子になっている。 10 11# 入れ子判定プログラム本体 12def check(str) 13 count = str.size # => loopから抜けるために必要。 14 15 loop do # => 無限ループ。 16 str = str.gsub(/\(\)|\[\]|\{\}/, '') # => strから「かっこ」を削除。 17 str.size == count ? break : count = str.size 18 # str.size == count ? break : count = str.size 19 # これは三項演算子というものです。 20 # ============================== 21 # if str.size == count 22 # break 23 # else 24 # count = str.size 25 # end 26 # ============================== 27 # これと同じ意味です。少し短く書けるので使っています。 28 # この部分では繰り返しを続けるかどうかの判定を行っています。 29 # 文字列の長さが、「かっこ」を削除する前と同じなら 30 # loopを抜けて、違っていたら今の文字列の長さを 31 # countに新しく入れてloopを続けます。 32 end 33 34 str.size.zero? ? '入れ子です' : '入れ子ではないです' 35 # => loopを抜けた後の処理です。ここで返す文字列を選択しています。 36end 37 38sample = ['[]', '[]{}', '[()]{}', '([()]{})', '(])', '[](', '([)]'] 39# => テストに使う文字列を配列にして、一つずつ入力しなくて良いようにしています。 40 41sample.each do |e| # => sampleの中身を一つずつ取り出してeに入れています。 42 puts "『#{e}』は#{check(e)}。" # => eとcheckで処理した結果をputsで表示させます。 43end

考えてみました。このプログラムが正確に動くかどうかは分かりません。

投稿2017/06/16 09:57

編集2017/06/16 10:23
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問