회원 이름과 나이가 주어진다. 회원의 나이 순으로 정렬하되 같은 나이가 있을 경우 먼저 넣은 회원이 먼저 출력되게 하라.
처음 이 문제를 보았을 경우 값들을 받는 과정에서 이미 받았던 값인지 확인하고 그 값들은 기록하는 방식으로 진행하려고 했다.
예를 들어 21 Junkyu이 들어오고 21 Dohyun이 들어올 때 이미 21이 들어왔으니 21이라는 값 자체를 기억해두고 나이가 21인 것들끼리 다시 정렬하는 것이었다. 그러나 그럴려면 배열 안에서 이 값들이 어느 위치에 있고 어디서부터 어디까지 정렬을 할 것인지에 대한 문제와 또 그걸 위해서는 해당 배열들이 언제 들어와있냐를 통해 정렬이 되어야 하기 때문에 이건 도저히 아닌 것 같아 접었다.
애초에 값들을 받아서 저장을 할 때 나이,이름 거기에 더해 해당 번째가 반복문에 몇 번째 인지를 기록하는 방법이다. 이걸 기록해서 정렬을 다시 하면 될 거라 생각했다. 그런데 정렬을 두 번 한다면 그것은 그것대로 문제가 된다. 시간복잡도를 떠나서 이미 나이로 정렬했는데 다시 한 번 들어온 인덱스 수로 정렬을 하면 의미가 없다고 생각했다..그래서 파이썬의 내장함수 sort가 어떻게 돌아가는지를 찾아보려했는데 내장 라이브러리 자체가 c언어로 되어있고 상당히 복잠함을 알게 되었다. 그리하여 이 방법도 안됨을 알지만 코드를 끄적여보다 실패하고 접었다.
분명 막 어려운 문제는 아닌데 내가 파이썬도 그렇고 소팅을 어떻게 하는지에 대해서 감을 못 잡아서 풀지 못하였다. 결국 시간이 좀 흘러 서칭을 통해 확인해보았고 새로 알게 된 사실이 2개나 있다.
sort는 단순히 정렬을 하는 녀석인 줄 알았고, 다양한 추가 기능들을 제공하지 않을 거라고 생각했다.
그러나 sort는 자동적으로 우선순위를 가지고 정렬을 했다. 무슨 소리냐면
arr.append([int(age), idx, name]) -> 이렇게 arr에 값들을 넣었을 때
가장 먼저 age를 고려하고, 둘째로 idx, 마지막으로 name을 고려하는 것이다
만약에 age가 같다면 idx를 고려해서 정렬, idx마저도 같다면 name까지 고려하는 것이다.
그리하여 완성된 코드
import sys
input = sys.stdin.readline
n = int(input())
pList=[]
for idx in range (n):
age,name= map(str, input().split())
pList.append([int(age), idx, name])
pList.sort()
for idx in range(n):
print(f'{pList[idx][0]} {pList[idx][2]}')
위에 내용처럼 그냥 단순히 입력 받고 sort를 하면 안되는 이유가 정렬을 나이순으로 하고나서 같은 경우 이름을 보고 우선순위를 매기기 때문에 안된다.
그리하여 우리는 나이순으로만 정렬을 진행하려고 한다. 파이썬은 기본적으로 제공하는 것이 정렬 순서가 같은 경우에는 들어온 순서를 그대로 유지하는 속성이 있다고 한다. 그리하여 그냥 '나이순으로만'보고 정렬을 해도 이 문제를 해결할 수 있다.
import sys
input = sys.stdin.readline
n = int(input())
pList = []
for _ in range(n):
age, name = input().split()
pList.append([int(age),name])
pList.sort(key= lambda x: int(x[0]))
//lambda함수는 x파라미터를 가지고 int(x[0])을 돌려준다.
for _ in range(n):
print(f'{pList[_][0]} {pList[_][1]}')