括弧の試合で、コンパイラがスタックによって達成されるので、この問題を考える前に、まず、スタックのデータ構造を確認してください。
スタック:
スタック:後者はデータ構造の高度アウトがあり、その性質は、制限の特別なリスト(最後のアウト、スタックの先頭を)持っているだろう、我々は最初のコースは、プッシュ(プッシュ)とPOP(あるのだと考えるものをスタックを持ち上げますか?レッツ・プッシュを実装し、コードを通じてプロセスをポップ、)ポップ:
私たちは、スタックの最上部のこの部分に注意を払う必要があります:スタック(上)、我々は、スタックは一つのノードのみを持っていることを確認したいと次のノードへのリンク、具体的な実装では、新しいノード、次の新しいノード(ポインタ)を構築するポイントですオリジナルのスタック、スタックした後、新しいノードに集合。次のコードに示すように。
#プッシュを作成し、スタック構造をポップ
#まずlistnodeを定義します
クラスノード(オブジェクト):
デフ__init __(自己、値=なし):
self.value =値
self.next =なし
クラスのスタック(オブジェクト):
デフ__init __(自己):
self.node =ノード()
self.top = [self.node]
デフ(自己、elemは)プッシュ:
new_node =ノード(ELEM)
もしself.top [0] == .VALUEなし:
new_node.next =なし
他:
new_node.next = self.top [0]
self.top.append(new_node)
self.top.pop(0)
デフ(自己)ポップ:
試してみてください。
value_top = self.top [0] .VALUE
ノード= self.top [0] .next
self.top.append(ノード)
self.top.pop(0)
リターンvalue_top
除きます:
印刷(「間違って」)
S =スタック()
I [ '、 'B'、 'C'、 'D']にするため:
s.push(I)
範囲内のiについて(4):
印刷(s.pop())
問題と分析
問題は、leetcodeから茎
私たちはしばしば、我々は本当にこの原則を理解することができれば、対のブラケットかどうかを確認したいコンパイラ・プログラムは、私たちはコンパイラの原則を理解するのに役立ちますので、この問題は、非常に重要なことができます:
我々は最初の最も単純なケース考える:私たちは、それぞれ左括弧を右括弧とそのマッチング缶を持って聞かせて、ブラケットの同じタイプのすべての時間を、結論では、我々は左括弧(左)は、以下の式を有するカウントされます。
++左を左++左++
私たちは、さまざまな状況での左、閉じ括弧の顔を考えてみます。
= 0となし説明マッチング右括弧左、すなわち、発現がinvaildあり、括弧を残し
左 - - left--> 0左、我々は一致するように、左括弧と右括弧、我々は左に一致するようにしたい、この時間を持っています
すべてのシンボル、= 0、左!を横断した場合、式はまだ無効の指示であります
すべてのすべてで、私達はちょうど一致があるかどうかを確認するために、左括弧をカウントするために右括弧が必要ですが、これは単純なケースで、口座に異なるシンボル間の相対的な位置を取ることなく、次のような表現ならば、我々は上記をまとめます法律は成立していません。
(){}
更なる検討
興味深いパターンによると:鄭州ウィメンズ病院http://www.ytsgfk120.com/
効果的なブラケット表現上の興味深い特性は、サブ式の有効な式にも有効な式であるべきです。(必ずしもすべてのサブ式)。
各サブ式が有効な式であればここから我々はそれがあること、再帰的であることがわかり、式全体は、あなたが左まで削除するときに我々は、各サブ表現のマッチから式を解くことができるように、有効です空の式は、式が有効である説明:次のようにアルゴリズムのプロセスは、次のとおりです。
左括弧がスタックに遭遇しました。
スタックの最上位、試合が継続する場合は、スタックを起動します、右括弧が発生した。いない場合は、式全体が無効(invaild)で判断することができます。
スタックが空の場合は最後に、それは示し、式が、有効であるとして、私たちは、複雑さを減らすのに役立ちます辞書データ構造を使用して、次のとおりです。
#プッシュを作成し、スタック構造をポップ
#まずlistnodeを定義します
クラスノード(オブジェクト):
デフ__init __(自己、値=なし):
self.value =値
self.next =なし
クラスのスタック(オブジェクト):
デフ__init __(自己):
self.top =なし
デフ(自己、elemは)プッシュ:
new_node =ノード(ELEM)
self.top ==なしの場合:
new_node.next =なし
他:
new_node.next = self.top
self.top = new_node
デフ(自己)ポップ:
もしself.top =なし!
value_top = self.top.value
ノード= self.top.next
self.top =ノード
リターンvalue_top
他:
リターン偽
文字列= '()'
辞書_ = { '}': '{'、 ']': '['、 ')': '('}
デフjudge_str(str_、dict_):
S =スタック()
私str_中のため:
私dict_であれば:
結果= s.pop()s.top他に '#' の場合
もし(結果= dict_ [i]が!):
リターン偽
他:
s.push(I)
s.top ==なしの場合:
trueを返します
他:
リターン偽
judge_str(文字列、dict_)
概要
辞書形式がすぐに良い解決策になることができて、その後、式全体はまた、上に要約し、法律に基づいて、それを達成するためにスタック構造と一致している各サブ表現一致した場合結論として、我々ブラケットマッチングは、再帰的な構造であり、問題。
左括弧がスタックに遭遇しました。
(invaild)。スタックの最上位、試合が継続する場合は、スタックを起動します、右括弧に遭遇していない場合は、式全体が無効で判断することができます