71400


以下のコードを理解したく思っております。  
前回の質問は以下になるのですが、長くなるため、新しく質問させていただきました。

[前回の説明](https://ja.stackoverflow.com/questions/71288/%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E7%90%86%E8%A7%A3%E3%82%92%E6%B7%B1%E3%82%81%E3%81%9F%E3%81%84/71290?noredirect=1#comment78965_71290)

参照コード  
<https://gist.github.com/paveleremin/86dafdb4341244fc3a94#file-
gistfile1-js-L9-L30>

全体のコード

[code]

    function verify(str){
        // bracketsに()[]{}を代入
        var brackets = "()[]{}",
        // bracket,bracketPositionはなんらかのオブジェクト、stackは配列
            bracket,
            bracketPosition,
            stack = [];
      
        for (var i = 0, l = str.length; i < l; i++) {
          // 引数srtのインデックス番号をbracket変数に代入
            bracket = str[i];
      
            // bracketPosition変数にbrackets（つまり()[]{}）がbracket(つまりstr)の中にあるか探す機能のメソッドを代入（ある場合はカッコのインデックスを返す）
            bracketPosition = brackets.indexOf(bracket);
            // bracketPositionが−１を返す（つまりstrの中に()[]{}がない）場合は次の繰り返し処理を開始
            if (bracketPosition == -1) continue;
            // bracketPositionが偶数の時、stackにbracketPosition+1、つまり()[]{}のいづれかの閉じカッコがpushされる
            if (bracketPosition %2 === 0) {
                stack.push(brackets[bracketPosition+1]);
            }
            else if (stack.pop() !== bracket) {
                return false;
            }
        }
        // スタックが空っぽでないを返す
        return !stack.length;
      }
    
[/code]

上記コードの以下の箇所について意味をきちんと理解したいと思っています。

[code]

    else if (stack.pop() !== bracket) {
                return false;
    
[/code]

前回の説明にて

> else if (stack.pop() !==
> bracket)は，bracketPositionが奇数のとき，つまりbracketが閉じカッコであるときに呼び出されるコードです．スタックの最後から取り出し(popすると当然取り出した値はスタックから消えます)，それを期待する閉じカッコbracketと比較します．  
>  もし，期待する閉じカッコではない閉じ括弧であれば期待する条件を満たさないことが確定するのでfalseを返して終わるわけです．

との説明をしていただいたのですが、  
以下の認識は正しいでしょうか？アドバイスいただけますと幸いです。

bracketが閉じカッコであるとき、例えばその閉じカッコが")"だとします。  
そのときstack.pop() !== ")" となるわけですが  
この時点でstackには何が入っているのでしょうか？  
自分の推測ですと  
Stackにはなにも入っていない。  
ゆえにstack.popは空っぽという認識でおりますが、正しいでしょうか？

**追記**

下記の通り、for文のあとにconsole.logを仕込んで  
DevToolsで確認してみたのですが  
すいません、ちょっと意味が分かっておりません。

[code]

    function verify(str){
        // bracketsに()[]{}を代入
        var brackets = "()[]{}",
        // bracket,bracketPositionはなんらかのオブジェクト、stackは配列
            bracket,
            bracketPosition,
            stack = [];
      
        for (var i = 0, l = str.length; i < l; i++) {
          // 引数srtのインデックス番号をbracket変数に代入
            console.log(stack)
            bracket = str[i];
      
            // bracketPosition変数にbrackets（つまり()[]{}）がbracket(つまりstr)の中にあるか探す機能のメソッドを代入（ある場合はカッコのインデックスを返す）
            bracketPosition = brackets.indexOf(bracket);
            // bracketPositionが−１を返す（つまりstrの中に()[]{}がない）場合は次の繰り返し処理を開始
            if (bracketPosition == -1) continue;
            // bracketPositionが偶数の時、stackにbracketPosition+1、つまり()[]{}のいづれかの閉じカッコがpushされる
            if (bracketPosition %2 === 0) {
                stack.push(brackets[bracketPosition+1]);
            }
            else if (stack.pop() !== bracket) {
                return false;
            }
        }
        // スタックが空っぽでないを返す
        return !stack.length;
      }
    
      verify('a(aabbbccc');
    
    
    
    VM1444:11 []
    VM1444:11 []
    VM1444:11 [")"]
    VM1444:11 [")"]
    VM1444:11 [")"]
    VM1444:11 [")"]
    VM1444:11 [")"]
    VM1444:11 [")"]
    VM1444:11 [")"]
    VM1444:11 [")"]
    false
    
[/code]


CC BY-SA 4.0
2020-10-19T05:01:07.380
71320
2020-10-22T01:42:49.353
2020-10-20T04:32:21.060
39719
39719
question
javascript
stackの使い方について


> `bracketPosition = brackets.indexOf(bracket);`

には「括弧文字を探す」「括弧文字の開く閉じるを区別する」の２つの役目があります。 `bracketPosition`
が非負の時括弧文字であり、偶数の時は開く、奇数の時は閉じる、です（ここんところOK?）

> `if (bracketPosition %2 === 0)`

入れ子あり＝括弧は何個開いてもよいわけで、開括弧を見つけたときには判定は不要というか不可能です。閉括弧を見つけたときのために、括弧の種類を `push`
しておけばよいわけです。このソースコードにおいては `(` を見つけたときには `)` を `push` していることに注意（`{` 発見時に `}` を
`push` 以下同様）  
上記処理が `bracketPosition%2==0` のとき行われるのは理解できていますか？

そこまで理解できたなら、閉括弧を見つけたつまり `bracketPosition%2==0` でないとき即ち `else`
側に来た時の処理は明白でしょう。「正しい入れ子」とは「最後に見つけた開括弧を閉じる括弧文字がある」ということであり、なおかつ `stack`
には今「対応するべき閉括弧文字」が積まれているわけです。

閉括弧文字を見つけたとき `stack.pop()` で `)` が取り出された（ということは最も近い開括弧が `(`
であったということ）その見つけた閉括弧文字が `)` でないとは即ち入れ子になっていないので即 `return false;` してよいってことです。

んで、最後の文字まで来たときには開括弧が残っていない、すなわち `stack.length` が `0`
であることを確認すれば命題成立です（括弧文字が全くない特別例もこれに含まれる）


CC BY-SA 4.0
2020-10-22T01:42:49.353
71400
2020-10-22T01:42:49.353
8589
71320
answer