Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions 20.ValidParentheses_251019.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# 1st
(1回目の誤答)
```python
class Solution(object):
def isValid(self, s):
"""
:type s: str
:rtype: bool
"""
brackets = {'(': ')', '{': '}', '[' : ']'}
close_brackets = {')','}',']'}
correct_s = {}
for i in range(len(s)):
# 開かっこかどうか
if s[i] in brackets:
correct_s[i] = s[i]

# 閉じ括弧では何もしない
# open_orderに開き括弧の種類と配置順が入っている
{0:(,2:[)}
for i in range(len(s)):
if i in correct_s:
# 開括弧の次→閉じ括弧or開括弧の次に開括弧があれば最後の開き括弧の次が閉じ括弧で閉じ括弧は最後の開き括弧に対応する。
# 考慮する条件が多すぎるのでもっとシンプルな対応を確認する数え方がないか

# correct_sとsを比較する。

[()]
0 1 2


```

・後方の開かっこから順に、その開きかっこに対応する閉じ括弧が入っていればOK→スタックの問題
・正直、close_to_openにする理由がよくわからなかった。過去のレビューを見てもopen_to_closeが推奨されているので、こちらで回答する。
・open_to_closeの答えはまだ見ていない。


(2回目で正答、leetcodeではOK、AIではNG)
```python
class Solution(object):
def isValid(self, s):
"""
:type s: str
:rtype: bool
"""
open_brackets_stack = []
open_to_close = {'(': ')', '{': '}', '[' : ']'}
correct_s = ''
for char in s:
if char in open_to_close:
open_brackets_stack.append(char)
correct_s = correct_s + char
else:
correct_s = correct_s + open_to_close[open_brackets_stack.pop()] if open_brackets_stack else "#"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if 文と参考演算子が混在しているせいで読みにくく感じました。また、 1 行が長すぎるように感じました。 if 文で書き下したほうが読みやすくなると思います。

return s == correct_s and len(open_brackets_stack) == 0
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

まあ、いいんですが、s == correct_s にならない条件ってなんですかね。
open_to_close[open_brackets_stack.pop()] のあたりでもう分かりませんか。

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implicit false を利用し、

return s == correct_s and not open_brackets_stack

と書くことをおすすめします。

参考までにスタイルガイドへのリンクを貼ります。

https://google.github.io/styleguide/pyguide.html#2144-decision

For sequences (strings, lists, tuples), use the fact that empty sequences are false, so if seq: and if not seq: are preferable to if len(seq): and if not len(seq): respectively.

上記のスタイルガイドは唯一絶対のルールではなく、複数あるスタイルガイドの一つに過ぎないということを念頭に置くことをお勧めします。また、所属するチームにより何が良いとされているかは変わります。自分の中で良い書き方の基準を持ちつつ、チームの平均的な書き方で書くことをお勧めいたします。


```

・上記回答はAIレビューでNG箇所があったため検討
・NGの内容は以下の通り。
```python
# Pythonの三項演算子は「value_if_true if condition else value_if_false」で評価されるため、現在のコードは以下のように動作します:

# 現在のコード (問題あり)
correct_s = correct_s + open_to_close[open_brackets_stack.pop()] if open_brackets_stack else "#"
# 解析結果:
correct_s = (correct_s + open_to_close[open_brackets_stack.pop()]) if open_brackets_stack else "#"
# スタックが空の場合: correct_s = "#" (置き換え、追記ではない)
# 最終的にはs == correct_sの比較で正しい結果が得られていますが、これは偶然に頼っています。意図をより明確にするため、括弧で優先度を明示することをお勧めします:
```

(2回目の回答の修正)
```python
class Solution(object):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Python3では、class Solution: で大丈夫です。
もしかすると、leetcodeの設定がpython3になっていないのかもしれません。
pythonとpython3の2つが選べるようになっており紛らわしいのですが、昨今はpython3が主流と思われるので、特別な理由がなければpython3を選んでおいたほうが良さそうです。

def isValid(self, s):
"""
:type s: str
:rtype: bool
"""
open_brackets_stack = []
open_to_close = {'(': ')', '{': '}', '[' : ']'}
correct_s = ''
for char in s:
if char in open_to_close:
open_brackets_stack.append(char)
correct_s = correct_s + char
else:
correct_s = correct_s + (open_to_close[open_brackets_stack.pop()] if open_brackets_stack else "#" )
Comment on lines +85 to +89

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correct_s = correct_s + char ですが、forループを書き下すと '' + 's[0]' + 's[1]' + ... + 's[-1]' のようなイミュータブルなシーケンスの結合になっており、パフォーマンスの観点から避けるべきだと思います。

イミュータブルなシーケンスの結合は、常に新しいオブジェクトを返します。これは、結合の繰り返しでシーケンスを構築する実行時間コストがシーケンスの長さの合計の二次式になることを意味します。実行時間コストを線形にするには、代わりに以下のいずれかにしてください:

  • str オブジェクトを結合するには、リストを構築して最後に str.join() を使うか、 io.StringIO インスタンスに書き込んで完成してから値を取得してください
    ...

https://docs.python.org/ja/3.13/library/stdtypes.html#string-methods

return s == correct_s and len(open_brackets_stack) == 0

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correct_sという変数を設けずに実装する方がシンプルに感じます。
具体的にはopen_to_close[open_brackets_stack.pop()]charを比べることで、適切な閉じカッコかを確認します。そうすればループ中に不正な文字が来た時点で処理を打ち切ることができ、最後にはlen(open_brackets_stack) == 0の比較だけで済みます。

```


他の方の回答を見る
- https://github.com/h1rosaka/arai60/pull/8/files
・リンクのプッシュダウンオートマトンが気になるので後で見る。