자료구조 및 알고리즘/알고리즘

[알고리즘] 2019 카카오 개발자 겨울 인턴십 - 튜플

benjykim 2021. 1. 5. 17:43
반응형

2019 카카오 개발자 겨울 인턴십 - 튜플

url : https://programmers.co.kr/learn/courses/30/lessons/64065

2019 카카오 개발자 겨울 인턴십 - 튜플 문제를 풀며 익숙하지 않았던 것들에 대해 정리하고자 한다.

  • s = "{{1,2,3},{2,1},{1,2,4,3},{2}}" 라는 문자열이 주어지면, 해당 문자열을 ['1,2,3', '2,1', '1,2,4,3', '2'] 처럼 변경해야 했다.
  • 이 때, 나는 한 번에 숫자를 깔끔하게 나누는 것에 대해 미처 생각하지 못했다.

처음 나의 접근 방식

  1. s = "{{1,2,3},{2,1},{1,2,4,3},{2}}" 문자열을 나눌 때 s[1:-1]을 통해 양 사이드의 괄호를 제거했다.

  2. 그리고 나서 스택을 만들어 괄호에 따라 스택이 동작하게 했고, 만일 ',' 이 나온 경우엔 continue 를 하는 등 다소 복잡하게 생각했다. 대략 코드는 다음과 같이 작성했다.

    def solution(s):
        answer = []
        stack = []
        li = []
        s = s[1:-1]
        cnt = 0
    
        for ch in s:
            print("ch = ", ch)
    
            if ch == ',':
                continue
    
            if not stack:
                stack.append(ch)
                continue
    
            if ch == '{':
                stack.append(ch)
                continue
    
            if stack[-1] == '{' and ch == '}':
                stack.pop()
                tmp = []
                while li:
                    tmp.append(li.pop())
                li,append(tmp)
                cnt = 0
            else:
                cnt += 1
                li.append(ch)            
    
        ...
    
    # 위의 코드는 아래 1, 2, 5번의 문자열을 잘 파싱하지만, 3, 4와 같이 자릿 수가 2자리 이상인 경우는 파싱하지 못한다. 이걸 간과하고 계속 한자리수만 생각하며 코딩을 했다.
    1. S = "{{2},{2,1},{2,1,3},{2,1,3,4}}" / result = [2, 1, 3, 4]
    2. S = "{{1,2,3},{2,1},{1,2,4,3},{2}}" / result = [2, 1, 3, 4]
    3. S = "{{20,111},{111}}" / result = [111, 20]
    4. S = "{{123}}" / result = [123]
    5. S = "{{4,2,3},{3},{2,3,4,1},{2,3}}" / result = [3, 2, 4, 1]
    • 깔끔한 코드가 아니라 조잡하다. 뭔가 이상함을 감지했지만 깔끔한 파싱 방법이 마땅히 생각나지 않았다. 그래서 일단 카카오 해설을 보았다.
    • 해설을 보니, 접근 방법은 동일했다. 결국 문자열만 잘 해결하면 통과하는 문제였다...

내가 생각하는 깔끔한 코드

다른 분의 코드를 참고해서 위의 문제를 다시 풀어보았다. 코드는 아래와 같다.

def solution(s):
    answer = []
    # s = "{{2},{2,1},{2,1,3},{2,1,3,4}}"
    # s1 = ['2', '2,1', '2,1,3', '2,1,3,4']
    s1 = s.lstrip('{').rstrip('}').split('},{')
    new_s = []

    for i in s1:
        new_s.append(i.split(','))

    new_s.sort(key = len)

    for elem in new_s:
        tmp = set(elem) - set(answer)
        answer += (list(tmp))

    return [int(x) for x in answer]
  • 파싱 부분을 보니 현타가 온다. 다음부턴 서두르지 않고 효율적인 방법을 곰곰이 생각해봐야겠다.
  • lstrip(), rstrip() 함수 말고 replace()라는 함수를 생각했었지만 위의 방법보단 깔끔하지 않게 작성해야 할 것 같다.

lstrip(), rstrip(), strip(), replace() 정리

말 나온김에 이 네 가지 함수를 정리하려 한다.

rstrip(), lstrip(), strip()

  • rstrip() : 문자열 오른쪽 공백이나 인자로 넣은 문자열의 모든 조합 제거

  • lstrip() : 문자열 왼쪽 공백이나 인자로 넣은 문자열의 모든 조합 제거

  • strip(): 양쪽 문자열 공백이나 인자로 넣은 문자열의 모든 조합 제거

  • 예제

    >>> text = ' benjykim is blah blah '
    >>> print(text.rstrip())
    ' benjykim is blah blah'
    >>> print(text.rstrip('ah '))
    ' benjykim is blah bl'
    
    >>> print(text.lstrip())
    'benjykim is blah blah '
    >>> print(text.lstrip(' ben'))
    'jykim is blah blah '
    
    >>> print(text.strip())
    'benjykim is blah blah'

replace()

  • replace() : replace("검색 문자", "치환 문자", [,치환 횟수])

    >>> text = '123,456,789'
    >>> replaceAll = text.replace(",", "")
    >>> print(replaceAll)
    123456789
    
    >>> replaceOne = text.replace(",", "", 1)
    >>> print(replaceOne)
    123456,789
  • 리스트 치환 예제

    >>> list1 = ["apple", "orange", "melon", "banana"]
    >>> list2 = []
    >>> print("치환전:{0}".format(list1))
    "치환전:['apple', 'orange', 'melon', 'banana']"
    
    >>> for item in list1:
    >>>     #문자열 치환
    >>>     item_mod = item.replace("apple", "orange")
    >>>     # 새로운 리스트에 추가
    >>>     list2.append(item_mod)
    >>> print("치환후:{0}".format(list2))
    "치환후:['orange', 'orange', 'melon', 'banana']"
    
    # 출처 : https://ponyozzang.tistory.com/334
반응형