백준 문제 - 알파벳 찾기 풀이

권수민·2023년 8월 24일
2

문제 링크: https://www.acmicpc.net/problem/10809

나의코드

import string

def where_is(s):

    # list = [string.ascii_lowercase] 밑에랑 같은것
    lists = [chr(i) for i in range(97, 123)]
    # list.replace(','," ") 
    # list형태로는 replace 할 수 없어
    str = list(s.lower())
    index_char = 0

    for char in s:
        index_alpha = 0
        for alpha in lists:
            if char == alpha:
                lists[index_alpha] = index_char  
                #임시변수 i라 변경이 안되는것 : 직접 인덱스로 참조
                index_char += 1
                break
            index_alpha += 1
    return lists


def chage_rest(s):
    lists = where_is(s)
    index = 0
    
    for i in lists:
        # i = str(lists[index])
        # 하....str이라는 변수명을 사용하면서, 동시에 str()이라는 내장 함수도 사용하려고 했기 때문에 이 오류가 발생했습니다.
        i = str(i)
        if i.isalpha():
            lists[index] = -1
        index += 1
    # return(" ".join(str(lists))) 이렇게 하면 리스트화된 자료형 안에 " "가 추가
    return " ".join(
        [str(num) for num in lists]
    )  # 리스트 안에 쭉 넣어쥼.


where_is('baea')
print(chage_rest('baea'))하세요

string.ascii_lowercase
import string 해야 사용할 수 있으며, 한줄로 a-z소문자로 문자열을 만들어준다.
밑의 메소드 alphabet_list 또는
list = [chr(i) for i in range(97,123)] 같다.
다만 [string.ascii_lowercase]게 아니라 list(string.ascii_lowercase)로 씌워줘야 리스트로 변신.

def alpabet_list():
list = []
for i  in range(97,123):
        list.append(chr(i))
print(list)

chr()
chr()는 Python의 내장 함수 , chr(65)는 'A'를 반환한다

ord()
ASCII 또는 Unicode 코드값 반환

"".join()
이 함수는 구분자 문자열과 문자열 리스트의 요소를 연결하여 문자열로 만드는데, 여기서는 일단 리스트로 값을 받기 때문에 for문으로 하나하나 문자열로 변경한후 그것뒤에 공백 ' '에 join을 사용하여 각 문자열 사이에 공백이 들어가도록 만들어주려고 코드를 짠것.

돌아보는 시간

일단 함수의 시간복잡도는.... 또르르 O(n^2)이 되어 버렸다. for문을 중복사용했기 떄문이다.

시간복잡도 관련 링크 : https://velog.io/@stella_k/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EA%B0%9C%EB%85%90%EC%A0%95%EB%A6%AC

그리고 변수의 이름이 함수나 클라스 이름이랑 같게되면 인식하지 못하고 에러를 내게 된다.

위 코드에도 말했다 시피 str을 매개변수로 주었다가 str()을 사용하려니 계속 안되서 뭔 이유인가 한참 고민했었다!!!!

한줄 코드를 파이썬에서는 많이 사용하니 그것에 익숙해지는것도 필요하다!

일단,

더 좋은 코드가 있다.
같이 한 번 봐보겠다.

import string


def get_idx_naive(word):
    result = [-1]*len(string.ascii_lowercase)
    for i in range(len(word)):
        char = word[i]
        for j in range(len(string.ascii_lowercase)):
            lo = string.ascii_lowercase[j]
            if result[j] == -1 and char == lo:
                result[j] = i
    print(' '.join([str(num) for num in result]))


def get_idx(word):
    # point 1. ord
    # point 2. O(n^2) -> O(n)
    result = [-1]*len(string.ascii_lowercase)
    for i in range(len(word)):
        idx = ord(word[i]) - 97
        if result[idx] == -1:
            result[idx] = i
    print(' '.join([str(num) for num in result]))


get_idx_naive('baekjoon')
get_idx('baekjoon')

def get_idx_naive(word)함수와 나의 함수 차이점

일단 위의 get_idx_naive(word)는 나와 비슷하게 for문을 두번사용했지만 다르게 적은 부분이 있는거 같다.

먼저 -1의 리스트를 따로 만들어 a-z수만큼... 곱해주었다는 사실...................
이걸 알았다면 훨씬 간결하고 빠르게 만들 수 있었겠지만 아직 초보자로는 저렇게 생각이 가지 못했다;

두번쨰로는 바로 for문을 통해 바로 리스트 값을 거치는게 아닌 인덱스를 통해서 값을 지정해줬다는 사실이다.
for i in range(len(word) => 0 부터 len(word)-1값 까지 돌아간다.
for문으로 리스트를 돌다보면 => for i in word: 에서 i는 임시값으로 리스트안의 값을 바꿔줄 없기때문에 이방법이 훨씬 깔끔하고 효율적인 방법이었다.

def get_idx(word):함수와 나의 함수 차이점

여기서는 위의 차이점가 동일한 부분이 다르기도 하지만 일단 ord()라는 함수를 사용할 생각을 하지 못했다는 것이다.

ord()를 활용하면 위에서 말했다 시피 chr()와 반대로 아스키 코드 또는 유니코드의 값을 되돌려준다.
ord('a') => 97
이렇게 문자열이 아닌 수로 돌리면 훨씬 빠르고 간단한 방법으로 조건을 주어 두번 for문을 돌 필요가 없었던것이다..

일단 for문으로 word만 돌고 -> 또 다른 for문으로 a-z를 도는게 아니라 idx = ord(word[i]) - 97을 주면 a는 = 0 이 되니까 b = 1이 되고... 그렇게 인덱스로 맞춰주는 방식으로 시간복잡도를 빠르게 만든것...

그리고 ord(word[i]) - 97 = -1 일 때만 (바뀌지 않은곳, 왜냐 중복될때는 처음 바꿔준 인덱스를 기준으로 하기로 했기 때문에) 알맞게 바꿔주는 것으로 마지막 조건을 넣어 마무리했다.

이렇게 다른 사람의 코드를 보면서 한층 더 컴퓨터적 사고를 알아가는 기분이다!!

profile
초보개발자

0개의 댓글