Practice/알고리즘

알고리즘 스터디: 모음 제거, 진료 순서 정하기

밍미a 2022. 11. 18. 12:52
728x90

알고리즘 스터디: 모음제거

https://school.programmers.co.kr/learn/courses/30/lessons/120849

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

내코드:

import re
def solution(my_string):
    answer = ''
    answer = re.sub("a|e|i|o|u","",my_string)
    return answer

내가 이렇게 코드를 생각한 과정:

문제를 처음 봤을 때, 문자열 제거하는 방법에 대해 제일 먼저 생각했다. 문자열을 제거하는 방법이 일단 어떤 방법이 있는지 생각한 뒤 어떤 기준으로 문자를 제거해줘야할지 찾았고, 친절하게도 문제에 모음을 기준으로 문자열에서 모음을 빼라고 했으니까 분명 문자열을 제거하는 함수가 있을것이라고 생각을 했다. 처음 문제를 봤을때는 sub()함수의 존재를 몰랐지만 파이썬에서 문자제거 하는 방법을 검색하여 sub()함수에 대해 알 수 있었고, sub()함수만을 사용해서 비교적 쉽게 문제를 해결할 수 있었다.

익명의 하마님 코드:

def solution(my_string):
    vowels = ["a", "e", "i", "o" , "u"] # string으로 "aeiou"로 적어도 문제 없었다.
    for vow in vowels:
        my_string = my_string.replace(vow, "")
            
    return my_string

🧡나의 한줄 코멘트: replace() 라는 함수를 몰랐는데 replace()를 이용해서 풀 수 있다는 것을 알게되어 좋았다.

 


익명의 다람쥐님 코드:

def solution(my_string):
    삭제 = "aeiou"
    for i in range(len(삭제)):
        my_string = my_string.replace(삭제[i],"")
    return my_string
    # answer = my_string
    # for char in my_stirng:
        # if char in "aeiou":
            # answer = answer.replace(str, '')
    # return answer
    
    
    #my_string.replace('a', '')
    #my_string.replace('e', '')
    #my_string.replace('i', '')
    #my_string.replace('o', '')
    #my_string.replace('u', '')

🧡나의 한줄 코멘트: replace() 함수를 사용할때 인덱스를 활용해서 구현한것이 인상깊었다. 배열에 인덱스를 어떻게 적절이 활용하냐도 굉장히 중요한 포인트가 되는 것 같다.


익명의 알파카님 코드:

def solution(my_string):
    # str(my_string)
    # for i in my_string:
    # if i == 'a':
    #     my_string.remove('a','e','i','o','u')
    # answer = my_string
    # return answer
    
    # answer = [item for item in my_string if item != 'a' and item != 'e' and item !='i' and item != 'o' and item != 'u']
    # return answer
    # print(answer)
    
# 처참한 실패. 다른 함수를 찾아야겠다.

🧡나의 한줄 코멘트: 알고리즘을 풀지 못하더라도 어떤식으로 생각하고 접근하려고 했는지 느껴져서 좋았다.

 



알고리즘 스터디: 진료 순서 정하기

https://school.programmers.co.kr/learn/courses/30/lessons/120835

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


내코드:

 

import copy
#입력값
em = [3, 76, 24]
# 내림차순으로 정렬
#em 데이터값의 보호를 위해 대입연산자 (=)을 사용한 얕은 복사가 아닌, 객체를 새롭게 만들어주는 깊은 복사 coppy.deepcopy()를 사용해줌.
g = copy.deepcopy(em)
print(em)
g.sort(reverse=True)
print(em)
#빈 리스트 변수 만들어주기
int_list=[]
#오름차순 숫자 리스트 생성
for x in range(1,(len(em)+1)):
    int_list.append(x)

# 숫자랑 위급도 딕셔너리로 묶어주기
dictionary = dict(zip(g,int_list))

em_list = []
# 위급도 숫자만 추출해서 리스트에 넣어주기
for i in em:
    print(i)
    em_list.append(dictionary.get(i))
print(em_list)

내가 이렇게 코드를 생각 이유: 

이 문제는 내 수준에서 조금 어려운 문제였다. 일단 문제 분석을 우선적으로 했는데, 필요한 데이터가 무엇이 있을지 파악 하였다. 마침 " 응급실에 온 환자의 응급도를 기준으로 진료 순서를 정하려고 합니다." 라는 문구를 통해서 응급도와 진료 순서가 필요하겠다 라는 것을 알게 되었고, "응급도가 높은 순서대로 진료 순서를 정한 배열" 이 문구를 통해 대충 sort() 함수가 사용되겠다 라고 생각이 들었다. 어제 마침 스터디를 통해서 sort()함수를 알게 되었으니까 오늘 드디어 어제 배운것을 응용해볼 기회가 온것이다! 어제 "파이썬 알고리즘 인터뷰"라는 책을 살짝 읽었는데 enumerate()에 대해 살짝 나왔었다, enumerate는 인덱스를 자동으로 부여해줘서 튜플로 묶어주는건데 이걸로 어떻게 비벼볼 수 있지 않을까...? 생각을 하다가 인덱스 값이 0부터 시작하니까 거기다가 1을 더해줘야 1부터 나오는 순서가 만들어 질텐데.. 튜플은 값을 수정할 수 없다고 했으니까 뭐 좋은 방법이 없을까.. 생각하다가 딕셔너리 까지 생각이 도달했다..! 그리고 나는 결정했다 딕셔너리로 어떻게든 비벼보자고..! 일단 리스트로 들어온 emergency 값을 하나 복사해서 g라는 변수를 만든 후에 g를 큰 수대로 내림차순 되도록 g.sort(reverse=True)를 사용해 정렬하였다.  그리고 emergency 의 길이만큼 1부터 시작하는 숫자 리스트를 만들어준 후에 g(위급도) 변수와 딕셔너리로 엮어주면 되지 않을까!? 라고 생각했다.

사실 딕셔너리를 활용해서 문제를 푼것은 처음이었기 때문에 딕셔너리 활용방법이랑 키 값을 뽑아내는 방법등 모르는 부분은 검색을 통해 채워나가는 수 밖에 없었다.. 그래도 오늘 했으니까 다음번엔 안보고 할 수 있겠지라는 희망을 가지며 zip() 함수를 활용해 위급도랑 진료 순서를 딕셔너리로 묶어주었다.

그리고 emergency 배열을 for문으로 돌려서 emergency 값 하나를 키로 해서 진료순서를 answer 리스트에 저장할 수 있게 구현하였다.

 

그런데 여기서 한가지 문제가 생긴것이. 처음에 emergency 값을 대입연산자를 이용해 g = emergency  이런식으로 g 변수에 넣어주었는데. g를 정렬하니까 emergency 값도 같이 정렬되는 문제가 발생하였다. 이때만해도 얕은복사 깊은복사에 대한 개념이 없어서 한참 고민을 했다. 리스트가 애초에 참조변수인데.. 변수에 참조변수를 대입해주면.. 그 주소값을 넣어주는거니까.. 그래서 emergency의 값이 바뀌는 거구나..! 라는 것을 깨닳은 뒤 그럼 emergency 데이터를 보호하려면 어떻게 해야하지..? 자바면 new 연산자를 사용해서 객체를 복사할텐데.. 복사..? 파이썬도 객체를 복사하는 메서드가 있나..? 하면서 파이썬의 객체복사에 대해서 찾아보았다. 얕은복사, 깊은복사에 대해 나와있는 글을 발견해서 코드를 수정하였더니 코드가 잘 작동되었다.

익명의 하마님 코드:

def solution(emergency):
    emergency_list = [0] * len(emergency)
    for i in range(len(emergency)):
        
        emergency_list[emergency.index(max(emergency))] = i + 1
        emergency[emergency.index(max(emergency))] = 0
            
    return emergency_list
  
  # return (sorted(emergency, reverse=True).index(e) + 1 for e in emergency) # 한 줄에 끝내는 코드. 보고 박수쳤다. 알아두면 유용할 것 같다.

🧡나의 한줄 코멘트: 오.. max() 함수와 index()함수를 함께 쓸 수 도 있구나.. 이렇게 쓰는 방법도 있다는걸 배울수 있어서 좋았다.

 


익명의 다람쥐님 코드:

def solution(emergency):
    answer = []
    순서 = []
    
    for i in range(len(emergency)): # 그냥 emergency에 하니깐
        answer.append(emergency[i]) # null 뜸..
        
    sorted_answer = sorted(answer, reverse = True)
    
    for i in answer:
        순서.append(sorted_answer.index(i) + 1)
        
    return 순서

🧡나의 한줄 코멘트: 왜 그냥 emrgency 하면 null이 뜨는걸까...? 궁금해서 파이참에 복사해서 실행해봤더니..

TypeError: solution() takes 1 positional argument but 4 were given  오류가 떴다.. 같이 이야기 할 때는 됐던 것 같은데 뭐가 문제일까.. 한번 고민 해볼만 하겠다...


익명의 알파카님 코드:

# 방법1 
# 원래배열: emergency, 새로운배열: new
# new를 만들어 큰 순서대로 정렬한 뒤, 그 배열에 딕셔너리를 추가해 '위험도'와 '진료 순서' 부여.
# if문을 만들어, emergency와 'new의 위험도'가 같다면, 원래 배열을 new의 진료 순서로 할당.
# 문제점: 만약 중복된 원소가 생길시 방법을 생각해야 한다. 지금 실력으로 어떻게 손을 대야할지 모르겠다.

# 방법2
# 노가다! 반복문과 if문을 이용해 모든 원소를 돌면서 가장 큰 원소를 찾고 그 원소에 1을 부여.
# elif를 사용해 그 다음으로 큰 수를 찾아 다음 수를 부여 계속 반복 
# 문제점: 고식지계.. 임시방편임. 만약 emergency의 길이가 10 이상이다? 답이 없음. 그냥 망함.

# 방법3
# 구글링을 통해 적합한 함수를 찾는다. 모르겠다. 
# 다른 사람들의 의견을 들어보면, sorted를 이용한다 하였는데.. 어떻게 해야할까.

def solution(emergency):
    new[emergency.sort()]
    
    answer = []
    return answer

🧡나의 한줄 코멘트: 한가지 문제로 풀리지 않아 여러가지방 방법들을 생각해보고 고민해 본것이 너무 좋았다. 특히 중복된 원소가 생길 때와 같은 예외상황에 대해 한번 더 생각해본 자세는 보고 배워야 할 가치인듯 하다.

 


정리 해놓을 파이썬 이론 :

딕셔너리 활용법:

https://security-nanglam.tistory.com/427

 

[python] List to Dict (리스트를 딕셔너리로 변환) 총 정리!!

검색어 : List to Dict List 에서 Dict으로 변환하는 방법에는 여러가지 방법이 있습니다...! string_list = ['A','B','C'] 위와 같은 리스트가 있을때, 딕셔너리로 변환시키는 여러가지 방법들 ..! 1. Dictionary Com

security-nanglam.tistory.com

얕은복사, 깊은복사 cope.deepcopy():

https://blockdmask.tistory.com/576

 

[python] 파이썬 얕은복사, 깊은복사 (copy, deepcopy, [:], =) 총 정리

안녕하세요. BlockDMask입니다. 오늘은 파이썬 얕은 복사, 깊은 복사에 대해서 정리해보려 합니다. 은근히 헷갈려서 천천히 한번 정리해볼게요. 1. 파이썬 얕은 복사 2. 파이썬 깊은 복사 3. 그림으로

blockdmask.tistory.com

파이썬 문자제거 3가지 방법: 

https://codechacha.com/ko/python-remove-char-in-string/

 

Python - 문자열에서 특정 문자 제거, 3가지 방법

파이썬에서 문자열 안의 특정 문자를 제거하는 방법을 소개합니다. replace(A, B)는 문자열의 A를 모두 B로 변경합니다. 이 함수를 이용하여 특정 문자를 ''으로 변경하여 제거할 수 있습니다. sub(rege

codechacha.com


느낀점

오늘은 직접 생각했지만 함수를 몰라서 어려웠던 문제들이 많이 있었다. 지금은 연습이라 구글에서 함수를 검색해보며 공부하면서 문제를 풀어나갔다. 나름대로 논리적으로 생각하고 문제를 해결해나갔다는 점이 문제를 풀 고 난 후에도 여운처럼 계속 마음을 뿌듯하게 했다. 오늘 배운 이론들을 잘 정리해뒀다가 다음번에 또 활용할 수있도록 해야겠다.