71290


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

[コーディングテストで質問の意味がわかりません。](https://ja.stackoverflow.com/questions/71244/%e3%82%b3%e3%83%bc%e3%83%87%e3%82%a3%e3%83%b3%e3%82%b0%e3%83%86%e3%82%b9%e3%83%88%e3%81%a7%e8%b3%aa%e5%95%8f%e3%81%ae%e6%84%8f%e5%91%b3%e3%81%8c%e3%82%8f%e3%81%8b%e3%82%8a%e3%81%be%e3%81%9b%e3%82%93/71246?noredirect=1#comment78928_71246)

自分で日本語訳を付けてみましたが  
間違い箇所をご指摘いただければ幸いです。  
ちなみに言語はJavascriptです。

参照コード  
<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が２の倍数で割り切れる時、以下不明
            if (bracketPosition %2 === 0) {
                stack.push(brackets[bracketPosition+1]);
            }
            // そのほかはスタックの中の最後の要素とbracketが一致しない場合はfalseを返す
            else if (stack.pop() !== bracket) {
                return false;
            }
        }
        // スタックが空っぽを返す
        return !stack.length;
      }
    
[/code]

特にコード中にある

[code]

    stack.push(brackets[bracketPosition+1]);
    
[/code]

が理解できておりません。

`stack.push(brackets)`ならわかるのですが  
`stack.push(brackets[bracketPosition+1])`の  
`[bracketPosition+1]`はどういう意味になりますでしょうか？

また、関数は引数strの文字列にカッコが閉じられているかどうか調べる関数なのですが  
なぜスタックを使うとstrの文字列を調べられるのかがわかっておりません。

_**追記1**_

アドバイス、ご指摘ありがとうございます。  
私の方で以下を勘違いしているのかもしれません。

[code]

    brackets.indexOf(bracket);
    
[/code]

これはbrackets、つまり()[]{}が、bracket（引数strのこと）の中にあるか探すという意味で  
捉えているのですが、まずはこちらは正しいでしょうか？

そして、前回の回答文と今回に回答文の下記の文言がしっくりきていません。

**前回の回答文：ループでbrackets配列の文字を順番に取り出して、bracketに入れています。その位置が2で割り切れるとき、というのは括弧の最初の文字
"(","[","{"を指します。**

**今回の回答文：前回の質問でも回答されている通り偶数であれば開カッコであるといえます．例えば，striが'['であればこれは2です。**

bracketは引数strのことなので  
例えば引数strがa(aabbb)cccだとします。  
書き換えるとこうです。

[code]

    ()[]{}.indexOf(a(aabbb)ccc)
    
[/code]

indexOfは、文字列の中に指定した文字があるか探して、あればその位置を返してくれるので  
"("のIndex番号は１になります。

そして

[code]

    bracketPosition = brackets.indexOf(bracket)とあるので
    bracketPosition =　1
    
[/code]

になります。

上記の分で間違っている箇所はございますでしょうか？


CC BY-SA 4.0
2020-10-17T17:23:36.250
71288
2020-10-19T05:03:36.643
2020-10-19T05:03:36.643
39719
39719
question
javascript
コードの理解を深めたい


> `stack.push(brackets)`ならわかるのですが  
>  `stack.push(brackets[bracketPosition+1])`の  
>  `[bracketPosition+1]`はどういう意味になりますでしょうか？

`bracketPosition`
は`brackets.indexOf(bracket)`なので，マッチした文字が`brackets`の何文字目かが入っています．  
前回の質問でも回答されている通り偶数であれば開カッコであるといえます．例えば，`str[i]`(`str`のi+1文字目)が'['であればこれは`2`です．  
このとき，`brackets[bracketPosition]`は当然ながら`[`です．そして，`brackets[bracketPosition+1]`は`brackets`の次の文字……つまり対応する閉じカッコとなるので`]`です．これをスタックの最後に置いておきます．

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

最後の文字までループを回すと，条件をみたしていればスタックは空になっていることが期待されます．スタックにデータが残っていれば(`stack.length`が`0`でないならば)，まだ閉じられていない括弧があるということになるので．

[code]

    ex: (p: push / o: pop)
    aaaa(bbb[cc]dd)aaa
    ....p...p..o..o...
    => stack = []
    
    aaa(bbb(cc[ddd]ee
    ...p...p..p...o..
    => stack = [')',')']
    
[/code]

なので，スタックの中身が空かどうかが判断条件になるわけです．

* * *

ところで，質問文にコードをどこかから転載する場合は出典の明記に努めてください．ソースコードにも著作権はあり，ときに厄介になるので．
<https://gist.github.com/paveleremin/86dafdb4341244fc3a94#file-
gistfile1-js-L9-L30> のコードがほぼ一致しますが．（質問文のコードは謎の追記によるエラー箇所が見受けられますが……）

あと

> また、関数は引数strの文字列にカッコが閉じられているかどうか調べる関数なのですが

というのも少し違和感を覚える表現で，「文字列中の括弧の対応が正しいかを調べる表現」のほうがしっくりきます……

* * *

### 追記について

> 書き換えるとこうです。
[code]

>     ()[]{}.indexOf(a(aabbb)ccc)
>  
[/code]

この時点で認識に誤りがあります。(というか文字列はちゃんとクォーテーションで囲ってくださいね、擬似コードとしても意味が変わってしまいます)

`bracket`は`bracket = str[i]`です。これはループ内であり、`str`の`i`文字目です。  
`str`が`'a(aabbb)ccc'`であれば各ループにおいて `'a', '(', 'a', 'a', 'b', 'b', 'b', ')',
'c', 'c', 'c'`が順番に入ってきます。ですので、

[code]

    '()[]{}'.indexOf('(')
    
[/code]

のようになります。そして、[indexOf](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf)の返す
_n文字目_ は **0始まりです** 。  
なので、'('のindexは`1`ではなく`0`です。

如何でしょうか？


CC BY-SA 4.0
2020-10-17T18:34:46.590
71290
2020-10-18T05:15:09.393
2020-10-18T05:15:09.393
2376
2376
71288
answer