[SWEA]염라대왕의 이름 정렬 - Python3
문제
문제 복제를 금지한다 하여, 링크 첨부.
https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWqU0zh6rssDFARG
SW Expert Academy
SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!
swexpertacademy.com
입력
첫 번째 줄에 테스트 케이스의 수 T(1 ≤ T ≤ 50)가 주어진다.
각 테스트 케이스의 첫 번째 줄에는 이승 명부의 이름 개수 N(1 ≤ N ≤ 20,000)이 주어진다.
각 테스트 케이스의 두 번째 줄부터 N개의 줄에 걸쳐서 알파벳 소문자로 이루어진 이름들이 주어진다.
이름에는 공백이 포함되지 않으며 최소 1개, 최대 50개의 알파벳으로 이루어져 있다.
출력
각 테스트 케이스마다 ‘#x’(x는 테스트케이스 번호를 의미하며 1부터 시작한다)를 출력하고,
정리된 이름을 한 줄에 하나씩 출력하라. 같은 이름은 한 번만 출력해야 하는 것을 주의하라.
알고리즘
# 파일 입출력
f = open("s_input.txt", 'r')
lines = f.readlines()
# 파일에 쓰인 데이터 전처리
for i in range(len(lines)):
lines[i] = lines[i].split("\n")[0]
# 변수 선언
case_num = 0
cases = []
# 읽어온 모든 정보를 가지고 있는 배열 lines에서 데이터를 원하는 형태로 만들기 위해 반복 수행
for i in range(len(lines)):
# 테스트 케이스의 갯수를 저장
if i == 0:
case_num = lines[i]
# 하나의 테스트 안의 이름 갯수를 말해주는 단어인 경우
elif lines[i].isnumeric():
temp = []
# 다음 테스트 케이스 안의 이름 갯수를 말해주는 숫자를 만날 경우, 지금까지 구성해온 temp를 cases배열에 append
if lines[i].isnumeric():
cases.append(temp)
# temp 배열 안에 이름들을 append
else:
temp.append(lines[i])
# cases를 순회하면서, cases의 원소를 set자료구조를 이용해 중복을 제거하고 정렬
for i in range(len(cases)):
cases[i] = list(set(cases[i]))
cases[i].sort()
# 결과 출력
for i in range(len(cases)):
print("#", i+1)
for j in range(len(cases[i])):
print(cases[i][j])
설명
- 입력 파일인 s_input.txt를 읽기 모드로 연다.
- 파일에 쓰여있는 정보를 읽어오고, 원하는 모양으로 전처리해준다. 그 결과는 cases에 저장된다. cases는 2차원 배열의 형태로, [["my", "name", "is", "ho", "seok"], ["s", "s", "a", "m", ... , "d"]] 이런 식을 구성된다. 각 원소들은 하나의 테스트 케이스에서 나타나는 이름에 대한 정보를 담는ㄷ.
- cases의 각 원소인 1차원 배열을 set으로 바꿨다가 list로 바꿔준다. 이렇게 하는 경우 중복을 제거할 수 있다
- 중복을 제거한 cases의 원소를 정렬한다. sort()로 구현했다.
- 결과를 출력한다.
결과
원하는 결과를 출력한다.
후기
SWEA에서는 처음으로 알고리즘 문제를 풀어보았는데, 그리 어려운 문제는 아니었다. 다만 이 코드가 통과를 하는지를 좀 보고 싶은데, 뭐 데이터 입력과 결과 출력을 어떻게 해야한다는 건지 잘 이해가 안가서 이렇게 두었다. 다른 사람들의 풀이를 보니, 나와 거의 비슷하게 푼 사람이 통과를 한 것을 보면 나도 통과하지 않을까 하는 생각이 든다. 그리고, 중복을 제거하는 방법이 너무 후진거같다. set으로 바꿨다가 list로 바꾸는 방법보단, 해쉬를 이용한다든가 다른 메서드를 이용하는 것이 더 좋을 것 같다.