LoginSignup
0

More than 5 years have passed since last update.

[checkio] Brackets

Last updated at Posted at 2017-07-02

今回のは簡単だった(テストする度に例外的パターンを突きつけられた)
お題は与えられた文字列に含まれる(){}[]の括弧たちがそれぞれのスコープを守りつつ、キャッキャできているかを調べるというもの。
一人ぼっちやthird wheelがいてはいけない。

自分の回答

function brackets(expression){
    let openBrackets = [];

    for (let i of expression) {
        if (i.match(/[\(\{\[]/)) {
            openBrackets.push(i);
        }
        else if (i.match(/[\)\}\]]/)) {
            if (couples(openBrackets[openBrackets.length-1], i)) {
                openBrackets.pop();
            } else {
                return false;
            }
        }
    }
    if (openBrackets.length != 0) {
        return false;
    }
    else {
        return true;
    }


    //see if they are lovers
    function couples(a,b) {
        switch (a) {
            case "(":
            if (b!=")") return false;
            else return true;
            break;

            case "{":
            if (b!="}") return false;
            else return true;
            break;

            case "[":
            if (b!="]") return false;
            else return true;
            break;

            default:
            console.log(a+b+", something is wrong with these idiots!");
            return false;
        }
    }
}

相変わらず冗長。正規表現とswitch文を使って見て多少なりとも短くなるよう努力はしたんだけど・・・

すごいとおもったかいとう

function brackets(expression){
    let exp = expression.replace(/\d|[+\-*/]/g, ''),
        prev = '';

    while ( exp.length !== prev.length ) {
           prev = exp;
           exp = exp.replace('()', '')
                    .replace('{}', '')
                    .replace('[]', '');
    }

    return exp.length === 0;
}

すごくみじかいとおもいます!
2行目で数字と演算記号を除いたexp変数を定義。
3行目は空の変数。
5-10行目のwhileブロックは空のブラケットのカップルを見つける度に退場させていく。仲睦まじくなければそのカップルは戦場に残ってしまう。
全ての仲睦まじいカップルが退場したらおしまい。

例1) brackets("((({[(((1)-2)+3)-3]/3}-3))")
exp ... (({[((()))]})
1回目のwhile
exp ... (({[(())]})

例2) brackets("[1+1]+(2*2)-{3/3}")
exp ... [](){}
1回目のwhile
exp ... //全て退場

学び

string.match()

  • 引数に正規表現パターンを受け取って、stringにマッチするかtrue/falseを返す。

array.pop()

  • 配列の最後の要素を削除する。引数は特に取れないぽい。

正規表現でエスケープしなければいけない文字列について

  • +-*/や()などのブラケットなど、予約語としてそもそも機能を持っているものは文字列として受け取ってもらうために\(バックスラッシュ)を加える。ブラケット系以外のものに限っては、[]の一番最初の文字はエスケープしなくていいみたい。

反省

自分のとすごい人のではアプローチが違った。もっと柔軟にあれこれ考えられることが必要かも。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0