백준 온라인 저지 10989번 ‘수 정렬하기 3’
파이썬 알고리즘 문제풀이
문제
N개의 수가 주어졌을 때, 이를 오름차순으로 정렬하는 프로그램을 작성하시오.
입력
첫째 줄에 수의 개수 N(1 ≤ N ≤ 10,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 숫자가 주어진다. 이 수는 10,000보다 작거나 같은 자연수이다.
출력
첫째 줄부터 N개의 줄에 오름차순으로 정렬한 결과를 한 줄에 하나씩 출력한다.
소스코드
실패 소스 1 - 메모리 초과
입력을 받아 sorted로 정렬
1
2
3
4
5
6
7
8
9
10
11
12
13
N = input()
N = int(N)
series = [input() for n in range(N)]
sorted_series = sorted(series)
# .sort()를 쓰면 NoneType Error 발생
# sorted_series = series.sort() - 사용 ㄴㄴ
for i in sorted_series:
print(i)
실패 소스 2 - 메모리 초과
입력 값의 범위를 정함
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
N = input()
N = int(N)
if N <=10000000:
series = []
while len(series) != N:
a = int(input())
if a <= 10000:
series.append(a)
sorted_series = sorted(series)
for i in sorted_series:
print(i)
실패 소스 3 - 메모리 초과
값이 들어갈 10,000,000개의 빈 배열을 만들어 놓고 시작
1
2
3
4
5
6
7
8
9
10
11
12
13
N = int(input())
series = [None] * 10000000
for i in range(N):
a = int(input())
series[a] = a
abc = [b for b in series if b != None]
for i in abc:
print(i)
실패 소스 4 - 메모리 초과
삽입정렬을 사용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
N = int(input())
series = [None] * N
for i in range(N):
series[i] = input()
for j in range(2, N):
key = series[j]
i = j - 1
while i>0 and series[i] > key:
series[i+1] = series[i]
i = i - 1
series[i+1] = key
for num in series:
print(num)
실패 소스 5 - 런타임 에러
10,000개의 빈 배열을 만들어 놓고 시작
중복된 개수를 적기 위한 배열이 하나 더 있음
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
N = int(input())
series = [None] * 10000
number = [None] * 10000
for i in range(N):
a = int(input())
if series[a] == None:
series[a] = a
number[a] = 1
else:
number[a] = number[a] + 1
for b in series:
if b != None:
for i in range(number[b]):
print(series[b])
실패 소스 6 - 런타임 에러
위에서 사용되었던 중복 개수 배열을 없애고 enumerate
를 사용
1
2
3
4
5
6
7
8
9
10
11
12
N = int(input())
series = [0] * 10000
for i in range(N):
a = int(input())
series[a] = series[a] + 1
for c, num in enumerate(series):
if num != 0:
for d in range(num):
print(c)
실패 소스 7 - 런타임 에러
위의 enumerate 대신 len을 통해 index에 접근
입력 방법 변경 input()
-> (sys.stdin.readline())
1
2
3
4
5
6
7
8
9
10
11
12
import sys
N = int(input())
series = [0] * 10000
for i in range(N):
a = int(sys.stdin.readline())
series[a] = series[a] + 1
for b in range(len(series)):
if series[b] !=0:
for c in range(series[b]):
print(b)
실패 소스 8 - 메모리 초과
counting sort 사용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import sys
N = int(input())
series = []
for i in range(N):
series.append(int(sys.stdin.readline()))
counter = [0] * (max(series) + 1)
for i in series:
counter[i] += 1
ndx = 0
for i in range(len(counter)):
while 0 <counter[i]:
series[ndx] = i
ndx += 1
counter[i] -= 1
for num in series:
print(num)
성공 소스 1
최백준선생님의 코멘트에 따라 생성 리스트의 크기를 10,000에서 10,001로 바꾸었더니 성공..
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import sys
N = int(input())
series = [0] * 10001
for i in range(N):
a = int(sys.stdin.readline())
series[a] = series[a] + 1
for b in range(len(series)):
if series[b] !=0:
for c in range(series[b]):
print(b)
성공 소스 2
딕셔너리 사용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import sys
N = int(input())
dic = {}
for i in range(N):
a = int(sys.stdin.readline())
if a in dic:
dic[a] = dic[a] +1
else:
dic[a] = 1
for sorted in sorted(dic.items()):
for i in range(sorted[1]):
print(sorted[0])
배운 것
위에 포함된 개념들 - ‘Counting Sort’ 및 ‘삽입정렬’과 그리고..
1. 딕셔너리에서 키를 찾을 때 없을 경우, None이 아니라 KerError를 raise 함.
그래서 아래와 같이 key 값이 있는지를 확인해야 함. == None
은 사용 불가
1
2
3
4
5
6
7
8
for i in range(N):
a = int(sys.stdin.readline())
if a in dic:
dic[a] = dic[a] +1
else:
dic[a] = 1
2. 배열을 초기화할 때는 아래와 같이 사용
1
new_list = [None] * n
3. sys.stdin.readline()
가 input()
보다 빠르다고 한다.
코멘트
여덟시간 가까이 시도하면서 배운 것도 참 많다. 그리고 알고리즘 풀이는 재미있다.
그리고.. 문제를 제대로 읽고 꼼꼼하게 생각했으면 이렇게 오래 걸리지 않았을텐데, 내 경험과 능력도 부족했고 또 성급하기도 해서 한참을 돌아왔다. 배운 것도 참 많긴 하지만.. 뭐랄까 진짜로 하나 하나 배울수록 내가 얼마나 모르고, 그리고 컴퓨터라는 게 얼마나 복잡한지 알아가는 것 같다. 계산기라는 것의 원리도 한번 제대로 배우고 싶기도 하고..