[프로그래머스] 숫자 문자열과 영단어 python

kiki·2022년 2월 5일
1

프로그래머스

목록 보기
4/73

문제 링크

https://programmers.co.kr/learn/courses/30/lessons/81301

문제 설명

간략하게 문제를 설명하자면, 영어와 숫자로 섞여있는 문자열을 받아 순숫자(?)의 형태로 return 하는 것.

ex) "one4seveneight" → 1478 (not str!)

1차 시도 - 맞는 코드

def solution(s):
    arr = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']
    tmp = ""
    result = ""
    for i in range (len(s)):
        c = s[i]
        if(c.isnumeric()):
            result+=c
        else:
            tmp+=c
            if tmp in arr:
                result+=str(arr.index(tmp))
                tmp=""
    return int(result)

코드 설명 : for문으로 문자열을 돌면서 숫자면 바로 result에 추가하고, 문자면 임시 문자열에 추가해서 임시 문자열의 단어가 미리 정의해둔 배열 내에 존재하는 숫자 단어인지 확인 후 맞으면 최종 return 문자열에 추가한다. (아닐 경우엔 다시 for문을 돌아 else문으로 돌아와 단어가 완성 될 때까지 임시 문자열을 완성한다.

처음엔 이렇게 작성하지 않았었고 지하철에서 작성 후에 학교 와서 프로그래머스에서 실행 해보고 안되는 부분을 고친 코드다.

내가 잊었었고 몰랐던건,

  1. 문자열 내에서 for문을 돌진 못한다. -> 돈다. 바보다. 저렇게 안해도 됐었다. 지금 보니까 할 수 있군.
  2. isnumeric() 함수는 string 함수. 인자로 값을 넘겨주는게 아니라 str.isnumeric() 이렇게 쓰는 것.
  3. 문자열엔 append 가 아니라, + 쓰면 된다. (join 함수는 리스트를 문자열로 합쳐주는 것.)
  4. 배열의 .index() 함수. 리스트 내에서 인자로 들어오는 값의 위치를 반환한다.

내가 알았던 건,

  1. 배열로 미리 정의해두고 같은게 있나 찾으면 되겠군!
  2. 숫자인지 확인하고 아니면 임의의 변수에 저장해두면 되겠군!

1-2차 시도 - 맞는 코드

def solution(s):
    result = ""
    tmp = ""
    arr = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']

    for j in s:
        if(j.isnumeric()):
            result+=j
        else:
            tmp+=j
            if tmp in arr:
                result+=str(arr.index(tmp))
                tmp=""
    return int(result)

for문으로 굳이 문자열에 인덱스로 접근할 필요가 없다.
처음 생각했던 대로 문자열 내에서 for문을 돌아서 문자를 하나씩 가져오면 편리!

첫번째 코드를 생각보다 빨리 작성해서 다른 풀이 방법이 없을까 생각하던중

replace() 함수가 있는지 없는지 잘은 기억 안나지만 있다면 매우 유용하겠군! 그리하여 replace() 함수를 찾아보고 작성한 두번째 코드.

2차 시도 - 틀린 코드

def solution(s):
    dic = {'zero':0, 'one':1, 'two':2, 'three':3, 'four':4, 'five':5, 'six':6, 'seven':7, 'eight':8, 'nine':9}
    for string, num in dic:
        s.replace(string, num)
    return s

와 replace 쓰니까 엄청 간단하네? 생각.

하지만 다 틀림.

  1. for string, num in dic -> 이 형식으로 받아오려면 dic이 아니라 dic.items() 로 가져와야한다.
  2. replace() 함수는 replace 된 문자열을 return 할 뿐이지, 실제로 문자열 자체를 변경하진 않는다.
  3. dic 내에서 string과 int 쌍으로 묶어뒀는데 replace 하려면 str끼리만 replace 가 가능했다.
  4. 문제에서 요구하는 return 타입은 int. (첫번째 코드에서도 이걸 잘못썼었다.)

2-2차 시도 - 맞는 코드

def solution(s):
    dic = {'zero':'0', 'one':'1', 'two':'2', 'three':'3', 'four':'4', 'five':'5', 'six':'6', 'seven':'7', 'eight':'8', 'nine':'9'}
    for key in dic:
        s = s.replace(key, dic[key])
    return int(s)

틀린 부분을 모두 고쳐준 코드이다.

프로그래머스에서 코드를 입력하고 보니 이게 왠일? 두번째 코드가 모든 풀이에서 가장 상위에 있는 코드와 매우 유사했다. 기분이 좋았다.

정말로 파이썬 공부가 시급해지는 때이다.

결론

  1. 문자열 내에서 for문 돌 수 있다. (쓰기 창피할 정도로 기초여서 쓰고싶지 않지만...)
  2. str.isnumeric() 함수를 이용해 해당 문자열이 숫자인지 아닌지 확인할 수 있다. +추가로 .digit() 함수도 있다.
  3. 문자열을 합치는 건 +를 사용해 합치면 된다.
  4. arr.index(tmp) 함수를 이용해 tmp에 해당하는 요소의 index를 반환받을 수 있다.
  5. dictionary는 {'name':'chaewon', 'age':23} 이런 형식.
  6. dic.items() 를 이용해 key와 value를 한꺼번에 가져올 수 있다. (딕셔너리로 for문을 돌때 유용)
  7. replace 함수는 replace된 문자열은 반환할 뿐 실제 문자열을 변경하지는 않는다.
  8. enumerate 함수는 숫자와 요소를 함께 반환한다. (인덱스와 요소를 함께 받고싶을때 사용하기 좋다)

추가 메모

딱 한달 전에 푼 문제였다. 지금 보니깐 간단하게 바로 생각나서 연습의 중요성을 깨닫는 중(아직 많이 부족하지만...)

다시 풀어보았따.

def solution(s):
    arr = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']
    for i,c in enumerate(arr):
        s = s.replace(c,str(i))
    return int(s)

처음엔 enumerate 쓰지 않고 range써서 복잡하게 코드 작성했는데 enumerate를 사용하면 이렇게 편리하다니!
리스트나 문자열에서 인덱스와 요소를 함께 받고 싶으면 enumerate를 사용하면 편리하다.
열심히 공부하자

+) replace 함수의 인자는 변환 대상, 변환할 문자, 그리고 count! count를 지정해주면 count 갯수 만큼만 replace 된다. 예를 들어 'oxoxoxoxox'.replace('ox', '', 1) 이렇게 써주면 첫번째 ox만 로 replace 된다.

0개의 댓글