기록

프로그래머스_python_순위 검색 본문

코딩테스트/python

프로그래머스_python_순위 검색

youngyin 2022. 1. 12. 19:04

문제

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

 

코딩테스트 연습 - 순위 검색

["java backend junior pizza 150","python frontend senior chicken 210","python frontend senior chicken 150","cpp backend senior pizza 260","java backend junior chicken 80","python backend senior chicken 50"] ["java and backend and junior and pizza 100","pyt

programmers.co.kr

풀이

1. 모든 경우의 수를 가지는 dict 만들기

"언어 직군 경력 음식"의 형태로 된 모든 key 값 구하기

[...
'cpp backend - pizza', 
'cpp backend - -', 
'cpp frontend junior chicken', 
'cpp frontend junior pizza', 
'cpp frontend junior -', 
'cpp frontend senior chicken'
...]

모든 key값에 대해서 100,001크기의 1차원 리스트를 할당

{...
'cpp backend - pizza' : [0, 0, 0 ... 0, 0],
'cpp backend - -' : [0, 0, 0 ... 0, 0], 
'cpp frontend junior chicken' : [0, 0, 0 ... 0, 0], 
'cpp frontend junior pizza' : [0, 0, 0 ... 0, 0], 
'cpp frontend junior -' : [0, 0, 0 ... 0, 0], 
'cpp frontend senior chicken' : [0, 0, 0 ... 0, 0]
...}

2. 매칭되는 모든 key에 info 값 저장하기

info를 바탕으로 매칭이 가능한 모든 key값 찾아 저장하기

  • 'java backend junior pizza 150'의 경우
'java backend junior pizza' : [0, 0, 0 ... 1, 0... 0, 0],
'java backend junior -' : [0, 0, 0 ... 1, 0... 0, 0],
'java backend - pizza' : [0, 0, 0 ... 1, 0... 0, 0],
'java backend - -' : [0, 0, 0 ... 1, 0... 0, 0],
'java - junior pizza' : [0, 0, 0 ... 1, 0... 0, 0],
'java - junior -' : [0, 0, 0 ... 1, 0... 0, 0],
'java - - pizza' : [0, 0, 0 ... 1, 0... 0, 0],
'java - - -' : [0, 0, 0 ... 1, 0... 0, 0],
'- backend junior pizza' : [0, 0, 0 ... 1, 0... 0, 0],
'- backend junior -' : [0, 0, 0 ... 1, 0... 0, 0],
'- backend - pizza' : [0, 0, 0 ... 1, 0... 0, 0],
'- backend - -' : [0, 0, 0 ... 1, 0... 0, 0],
'- - junior pizza' : [0, 0, 0 ... 1, 0... 0, 0],
'- - junior -' : [0, 0, 0 ... 1, 0... 0, 0],
'- - - pizza' : [0, 0, 0 ... 1, 0... 0, 0],
'- - - -' : [0, 0, 0 ... 1, 0... 0, 0]

3. 누적합 계산하기

각 리스트에 누적합을 저장하기 위해서

현재값 = 현재값+이전값

infoDict[key][sc] += infoDict[key][sc-1]

4. 쿼리문에 대답하기

[score이 t이상인 기록의 개수] = [score이 0이상인 기록의 수] - [score이 t-1이상인 기록의 수]를 이용

count = infoDict[mkey][-1]-infoDict[mkey][int(score)-1]

코드

from itertools import product

language = ["cpp", "java", "python", "-"]
jobGroup = ["backend", "frontend", "-"]
career = ["junior", "senior", "-"]
food = ["chicken", "pizza", "-"]
MAX_NUM = 100001

def solution(info, query):
    # 모든 경우의 수를 가지는 dict 만들기
    productList = product(language, jobGroup, career, food)
    infoDict = {" ".join(key):[0 for i in range(MAX_NUM)] for key in productList}
    
    # dict에 매칭되는 값 넣기
    for data in info : 
        lan, job, cr, fd, score = data.replace("and", "").split()
        tempProductList = product([lan, "-"], [job, "-"], [cr, "-"], [fd, "-"])
        for key in tempProductList : # 매칭되는 모든 key에 값 저장하기
            infoDict[" ".join(key)][int(score)] += 1
    
    # 누적합 계산하기
    for key in infoDict.keys() :
        for sc in range(1, MAX_NUM) : 
            infoDict[key][sc] += infoDict[key][sc-1]
    
    # 쿼리문에 대답하기
    ans = list()
    for qur in query : 
        *key, score = qur.replace("and", "").split()
        mkey = " ".join(key)
        ans.append(infoDict[mkey][-1]-infoDict[mkey][int(score)-1]) # sum(전체) - sum(~조건값-1)
        
    return ans
Comments