ericagong / algorithm_solving

2 stars 0 forks source link

[구현] 괄호변환 #9

Open ericagong opened 1 year ago

ericagong commented 1 year ago

⭐ 성찰

  1. 코테 할 때 제발 조용한 노래 듣기!!!!
  2. range(start, end, step)의 step 조건 잘 활용하기 [start, end) 임을 명심!
  3. while문보다는 for문을 사용하는 습관을 들이자: while 문 쓸 때 반드시 길이 조건도 명시하자!
  4. SRP가 잘 되도록, 함수를 생성하자! splitVU
  5. python으로 풀이하므로 python 함수 count, join, map, replace 등을 적극 활용하자.

❓ 문제 상황

👨‍💻 문제 해결: 완전탐색 + BFS

✅ 1차 풀이: 구현

def is_right(w): if not w: return False s = [] for p in w: if p == '(': s.append('(') elif p == ')': if not s: return False s.pop() return True if not s else False

def convert(w): s = '' for i in w: if i == '(': s += ')' else: s += '(' return s

def trans(w):

1

if not w:
    return ''
# 2
u = w[:2]
i = 2
while not is_balance(u): # 최소 올바른 수열을 뽑는 부분에서 길이 조건 명시하지 않아 무한루프
    if i >= len(w):
        break
    i += 2
    u = w[:i]
v = w[len(u):]
# 3
if is_right(u):
    t = trans(v)
    return u + t
# 4
else:
    s = '('
    t = trans(v)
    s += t + ')'
    s += convert(u[1:-1])
    return s

def solution(p): if is_right(p): return p else: return trans(p)

### ✅ 1차 풀이 - 코드 변경
> range 문의 step을 이요해서 더 간단하게 풀이 가능
- while문보다는 범위와 종료 조건이 명확한 for문을 range(start, end, step) 사용해 풀이
```python
def is_right(p):
    cnt = 0
    for s in p:
        if s == '(':
            cnt += 1
        else: 
            if cnt <= 0:
                return False
            else: 
                cnt -= 1
    return cnt == 0

def is_balanced(p):
    return p.count('(') == p.count(')')

def toggle(p):
    ret = ''
    for s in p:
        if s =='(':
            ret += ')'
        else:
            ret += '('
    return ret

def solution(p):    
    if not p:
        return p
    for i in range(2, len(p)+1, 2):
        u = p[0:i]
        v = p[i:]
        if is_balanced(u):
            break
    if is_right(u):
        return u + solution(v)
    else:
        ret = '(' + solution(v) + ')'
        ret = ret + toggle(u[1:-1])
        return ret 

✅ 2차 풀이: ()의 숫자를 카운트하여 u, v를 간단하게 분리

  1. cnt 변수 카운팅을 통한 균형잡힌 문자열 u, v의 빠른 분리:
    • 올바른 최소 괄호 = '('와 ')'의 수가 최초로 맞아 0이 되는 경우.
  2. map 함수에 lambda 함수를 적용해 굳이 별도의 함수 만들지 않고, 배열 전체에 특정 함수 적용하기 -> 간결하게 코드 작성 가능
  3. 리스트를 ''.join(리스트) 형식으로 문자열로 변환.
    
    def is_right(p):
    cnt = 0
    for i in range(len(p)):
        if p[i] == '(':
            cnt += 1
        else:
            if cnt <= 0:
                return False
            else:
                cnt -= 1
    return cnt == 0

def solution(p): if not p: return '' right = True cnt = 0 for i in range(len(p)): if p[i] == '(': cnt += 1 else: cnt -= 1 if cnt == 0: u = p[:i+1] v = p[i+1:] if is_right(u):

            return u + solution(v)
        else:
            return '(' + solution(v) + ')' + ''.join(list(map(lambda x: ')' if x == '(' else '(', u[1:-1])))

### ✅ 3차 풀이: 구현에 충실하면서 pythontic하게 풀이
- 굳이 별도의 함수 만들지 않고, python이 제공하는 함수 `문자열.count('문자')`, `문자열.replace('바뀔 문자열', '바꿀 문자열')` 사용해 간략하게 표현
```python
def solution(p):
    ...
    if correct(u): return u + solution(v)
    else:
        return '(' + solution(v) + ')' + u[1:len(u)-1].replace('(','0').replace(')','(').replace('0',')')

def balanced(b): return b.count('(') == b.count(')')

...
ericagong commented 1 year ago

🤔 Be Pythontic!