かっこを変換[programmers/CodingTest/Python]
14102 ワード
問題の説明
新しい開発者としてココアに入った「康」は、先輩の開発者から仕事の任務を受け、他の開発者が書いたソースコードを分析し、問題を発見し、修正するように要求された.ソースコードをコンパイルしてログを表示すると、ほとんどのソースコードのカッコがペアではない形式で記述されているため、エラーが発生します.
変更するソースファイルが多すぎるため、conはソースコードからカッコをすべて抽出し、カッコ文字列を正しい順序で表示するプログラムを開発することを検討しています.
用語定義
文字列が「(」と「)」のみで構成され、「(」の数と「)」の数が同じである場合は、バランスカッコ文字列と呼ばれます.
「(」と「)」のカッコが一致している場合は、正しいカッコ文字列と呼ばれます.
たとえば、文字列「()」(「」など)は「カッコ文字列のバランス」ですが、「有効カッコ文字列」ではありません.
逆に、文字列(()()などは「バランスのとれたカッコ文字列」であり、「正しいカッコ文字列」でもあります.
「(」と「)」のみからなる文字列wが「バランスの取れた括弧文字列」である場合、以下の手順で「正しい括弧文字列」に変換できます.1. 입력이 빈 문자열인 경우, 빈 문자열을 반환합니다.
2. 문자열 w를 두 "균형잡힌 괄호 문자열" u, v로 분리합니다. 단, u는 "균형잡힌 괄호 문자열"로 더 이상 분리할 수 없어야 하며, v는 빈 문자열이 될 수 있습니다.
3. 문자열 u가 "올바른 괄호 문자열" 이라면 문자열 v에 대해 1단계부터 다시 수행합니다.
3-1. 수행한 결과 문자열을 u에 이어 붙인 후 반환합니다.
4. 문자열 u가 "올바른 괄호 문자열"이 아니라면 아래 과정을 수행합니다.
4-1. 빈 문자열에 첫 번째 문자로 '('를 붙입니다.
4-2. 문자열 v에 대해 1단계부터 재귀적으로 수행한 결과 문자열을 이어 붙입니다.
4-3. ')'를 다시 붙입니다.
4-4. u의 첫 번째와 마지막 문자를 제거하고, 나머지 문자열의 괄호 방향을 뒤집어서 뒤에 붙입니다.
4-5. 생성된 문자열을 반환합니다.
パラメータとして「カッコ文字列のバランス」pを指定した場合、解法関数を完了し、指定したアルゴリズムを実行して「正しいカッコ文字列」に変換した結果を返します.
パラメータの説明
1. 입력이 빈 문자열인 경우, 빈 문자열을 반환합니다.
2. 문자열 w를 두 "균형잡힌 괄호 문자열" u, v로 분리합니다. 단, u는 "균형잡힌 괄호 문자열"로 더 이상 분리할 수 없어야 하며, v는 빈 문자열이 될 수 있습니다.
3. 문자열 u가 "올바른 괄호 문자열" 이라면 문자열 v에 대해 1단계부터 다시 수행합니다.
3-1. 수행한 결과 문자열을 u에 이어 붙인 후 반환합니다.
4. 문자열 u가 "올바른 괄호 문자열"이 아니라면 아래 과정을 수행합니다.
4-1. 빈 문자열에 첫 번째 문자로 '('를 붙입니다.
4-2. 문자열 v에 대해 1단계부터 재귀적으로 수행한 결과 문자열을 이어 붙입니다.
4-3. ')'를 다시 붙입니다.
4-4. u의 첫 번째와 마지막 문자를 제거하고, 나머지 문자열의 괄호 방향을 뒤집어서 뒤에 붙입니다.
4-5. 생성된 문자열을 반환합니다.
I/O例
p result
"(()())()" "(()())()"
")(" "()"
"()))((()" "()(())()"
I/O例説明
I/O例#1
すでに「有効な括弧文字列」です.
I/O例#2
2つの文字列
- u = ")("
- v = ""
-vに対してステップ1からの再帰操作を実行すると、空の文字列が返されます.
-uの前後の文字を削除し、残りの文字の括弧の方向を反転すると「」になります.
-したがって、生成された文字列は「(+)」「+」「+」「+」であり、最終的に「()」に変換されます.
2つの文字列
- u = "()"
- v = "))((()"
- u = "))(("
- v = "()"
-vに対して1ステップ目からの再帰操作が実行された場合は「()」を返します.
-uの前後の文字を削除し、残りの文字の括弧の方向を反転すると「()」になります.
-したがって、生成された文字列は「(」+「()」+「()」であり、最終的には「()()」を返します.
方法
この問題は実施問題で,与えられた条件に従って再帰関数で書く最初は問題が理解できず、少し時間がかかりましたが、一歩一歩関数で実現して解決することができます.
次の関数を記述して解きました
cutting関数は、条件に従って
逆関数
sをパラメータとして宣言し、
->「(」と「)」のカウント変数cnt 1、cnt 2は0です.
->sの長さが繰り返されるiのfor文.
-->
s[i]
が「(」の場合、cnt 1が増加します.-->その他の場合はcnt 2を増やします.
-->cnt 1とcnt 2が同じ場合はiを返します.
->
s의 길이-1
に戻ります.->「(」と「)」のカウント変数cnt 1、cnt 2は0です.
->sの長さが繰り返されるiのfor文.
-->
s[i]
が「(」の場合、cnt 1が増加します.-->その他の場合はcnt 2を増やします.
->cnt 1とcnt 2が同じ場合はTrueを返します.
->そうでなければfalseを返します.
->スタックとして使用するリストスタックを宣言します.
->sの長さが繰り返されるiのfor文.
-->
s[i]
が「(」)、----->スタックに
s[i]
を入れます.-->その他、
----->スタックが空の場合、
------>falseに戻ります.
----->スタック
pop()
.->Trueに戻ります.
->sをリストに変換します.
->sの長さが繰り返されるiのfor文.
-->
s[i]
が「(」)、-->
s[i]
が「」に更新されました.-->その他、
-->
s[i]
が「(」に更新されました.->sは文字列を返します.
->sが空の文字列の場合、空の文字列が返されます.
cutting(s)
の戻り値を変数idxに格納し、切り取り>sのインデックスを保存します.->2つの文字列u,vをそれぞれ
s[:idx+1]
,s[idx+1:]
と表す.->
checking(u)
が真の場合、-->
u+change(v)
に戻ります.->
checking(u)
がfalseの場合、-->一時変数tmpを
'('+change(v)+')'+opposite(u[1:-1])
と宣言します.-->tmpを返します.
change(p)
に選択します.solution.py def solution(p):
def cutting(s):
cnt1, cnt2=0, 0
for i in range(len(s)):
if s[i]=='(':
cnt1+=1
else:
cnt2+=1
if cnt1==cnt2:
return i
return len(s)-1
def counting(s):
cnt1, cnt2=0, 0
for i in range(len(s)):
if s[i]=='(':
cnt1+=1
else:
cnt2+=1
if cnt1==cnt2:
return True
else:
return False
def checking(s):
stack=[]
for i in range(len(s)):
if s[i]=='(':
stack.append(s[i])
else:
if not stack:
return False
stack.pop()
return True
def opposite(s):
s=list(s)
for i in range(len(s)):
if s[i]=='(':
s[i]=')'
else:
s[i]='('
return ''.join(s)
def change(s):
if not s:
return ''
idx=cutting(s)
u, v=s[:idx+1], s[idx+1:]
if checking(u):
return u+change(v)
if not checking(u):
tmp='('+change(v)+')'+opposite(u[1:-1])
return tmp
answer = change(p)
return answer
Reference
この問題について(かっこを変換[programmers/CodingTest/Python]), 我々は、より多くの情報をここで見つけました
https://velog.io/@xx0hn/Programmers-CodingTest-Python-괄호-변환
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
def solution(p):
def cutting(s):
cnt1, cnt2=0, 0
for i in range(len(s)):
if s[i]=='(':
cnt1+=1
else:
cnt2+=1
if cnt1==cnt2:
return i
return len(s)-1
def counting(s):
cnt1, cnt2=0, 0
for i in range(len(s)):
if s[i]=='(':
cnt1+=1
else:
cnt2+=1
if cnt1==cnt2:
return True
else:
return False
def checking(s):
stack=[]
for i in range(len(s)):
if s[i]=='(':
stack.append(s[i])
else:
if not stack:
return False
stack.pop()
return True
def opposite(s):
s=list(s)
for i in range(len(s)):
if s[i]=='(':
s[i]=')'
else:
s[i]='('
return ''.join(s)
def change(s):
if not s:
return ''
idx=cutting(s)
u, v=s[:idx+1], s[idx+1:]
if checking(u):
return u+change(v)
if not checking(u):
tmp='('+change(v)+')'+opposite(u[1:-1])
return tmp
answer = change(p)
return answer
Reference
この問題について(かっこを変換[programmers/CodingTest/Python]), 我々は、より多くの情報をここで見つけました https://velog.io/@xx0hn/Programmers-CodingTest-Python-괄호-변환テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol