[Python] 정렬 - 숫자, 문자열, 문자열 리스트, 오름차순 및 내림차순

2023. 1. 29. 00:03파이썬(Python)

반응형

1. 숫자

- sort() : 리스트의 원소를 오름차순으로 정렬한다.

arr=[15,64,32,78,36,98,22]
arr.sort()
print(arr)

 

결과

[15, 22, 32, 36, 64, 78, 98]

 

- 내림차순으로 정렬 : sort(reverse=True)

arr=[15,64,32,78,36,98,22]
arr.sort(reverse=True)
print(arr)

 

결과

[98, 78, 64, 36, 32, 22, 15]

 

- sorted() : 정렬된 리스트를 반환한다.

- 정렬 후의 리스트를 변수에 할당해야 한다.

arr=[15,64,32,78,36,98,22]
sort_arr=sorted(arr)
print(sort_arr)

 

결과

[15, 22, 32, 36, 64, 78, 98]

 

- sorted()에 reverse=True를 추가하면 내림차순으로 정렬할 수 있다.

arr=[15,64,32,78,36,98,22]
sort_arr=sorted(arr,reverse=True)
print(sort_arr)

 

결과

[98, 78, 64, 36, 32, 22, 15]

 

※ 내림차순 정렬

1. slicing

- sort()를 이용해 오름차순으로 정렬 후, 리스트를 뒤집어 내림차순으로 정렬한다.

arr=[15,64,32,78,36,98,22]
arr.sort()
sort_arr=arr[::-1]
print(sort_arr)

 

결과

[98, 78, 64, 36, 32, 22, 15]

 

2. reversed

- 오름차순으로 정렬 후, reversed로 정렬된 리스트를 감싸 내림차순으로 정렬한다.

- 다만, reversed를 사용 시 다시 list로 감싸줘야 내림차순 list를 반환받는다.

arr=[15,64,32,78,36,98,22]
arr.sort()
sort_arr=list(reversed(arr))
print(sort_arr)

 

결과

[98, 78, 64, 36, 32, 22, 15]

 


2. 문자열

- 문자열을 정렬하기 위해 sort()를 사용하면 에러가 발생한다.

- sort()를 사용하기 위해서 list를 만들어야 한다.

- 문자열의 각 문자를 갖는 list로 변환 후 sort 함수를 사용한다.

- 결과는 알파벳 사전 순서로 정렬된다.

- list를 join으로 각 원소를 합쳐 문자열로 만들어주면 정렬된 문자열을 얻을 수 있다.

string='python'
arr=list(string)
print(arr)

arr.sort()
sort_string=''.join(arr)
print(sort_string)

 

결과

['p', 'y', 't', 'h', 'o', 'n']
hnopty

 

- sorted()를 사용하면 문자를 원소로 하는 정렬된 리스트로 나온다.

- join으로 합치면 정렬된 문자열을 얻을 수 있다.

string='python'
sort_string_list=sorted(string)
print(sort_string_list)

sort_string=''.join(sort_string_list)
print(sort_string)

 

결과

['h', 'n', 'o', 'p', 't', 'y']
hnopty

 


3. 문자열 리스트

- 리스트 내에 n개의 단어가 있을 때 사전순으로 정렬하는 방법은 무엇일까?

- sort()를 사용하면 사전순으로 앞선 단어부터 정렬된다.

words=['computer','bed','banana','pencil']
words.sort()
print(words)

 

결과

['banana', 'bed', 'computer', 'pencil']

 

- 내림차순reverse=True를 추가한다.

words=['computer','bed','banana','pencil']
words.sort(reverse=True)
print(words)

 

결과

['pencil', 'computer', 'bed', 'banana']

 

- sorted 함수 이용

words=['computer','bed','banana','pencil']
words=sorted(words)
print(words)

words=['computer','bed','banana','pencil']
words=sorted(words,reverse=True)
print(words)

 

결과

['banana', 'bed', 'computer', 'pencil']
['pencil', 'computer', 'bed', 'banana']

 


Q) 짝짓기 후 최댓값

- N (짝수)과 N개의 숫자 입력

- 2개씩 짝을 지어 N/2개의 그룹을 만든다.

- 각 그룹에 있는 원소의 합 중 최댓값이 최소가 되도록 해라.

 

- 예를 들어, 6개의 숫자 5 7 3 4 9 1가 있다.

- [5,3], [4,7], [1,9]로 묶으면 각각의 합은 8, 11, 10이므로 최댓값은 11이다.

- 하지만 [1,9], [3,7], [4,5]로 묶으면 각각의 합은 10, 10, 9이므로 최댓값은 10이다.

- 따라서 최댓값이 10보다 작은 값은 없으므로 최솟값이 된다.

 

n=int(input())
arr=list(map(int,input().split()))

arr.sort()
max_val=0
for i in range(n//2):
    val=arr[i]+arr[n-i-1]
    max_val=max(max_val,val)
print(max_val)

 

결과

>> 6
>> 5 7 3 4 9 1
10

 

풀이)

- 예를 들어, 4개의 숫자가 있다고 가정하자. max(최댓값), min(최솟값), 임의의 수 a, b

- 이 수들은 다음과 같은 조건을 만족한다.

- max ≥ a, max ≥ b, min ≤ a, min ≤ b, max ≥ min

- 등호가 있는 경우는 4개의 수가 서로 다른 수가 아니기 때문이므로 같은 수일 경우까지 고려한다.

- max와 min이 같으면 4개의 수가 모두 같은 경우를 의미한다.

- 2개씩 묶으면 2개의 세트가 나오는데 3가지 경우가 나온다.

 

1. [max, a], [min, b]

- max+a와 min+b 중 더 큰 값은 무엇인가?

- 이 둘을 빼면 max+a-min-b가 되고 정리하면 (max-b)-(min-a)가 된다.

- max ≥ b이므로 max-b ≥ 0. min ≤ a이므로 min-a ≤ 0이 된다.

- (max-b)-(min-a) ≥ 0 이므로 max-b ≥ min-a가 되고 max+a ≥ min+b이 된다.

- 따라서 더 큰 값은 max+a가 된다.

 

2. [max, b], [min, a]

- a, b는 임의의 수이기 때문에 1과 같은 과정을 거치면 비슷한 결과가 나온다.

- 따라서 더 큰 값은 max+b이다.

 

3. [max, min], [a, b]

- max+min과 a+b 중 더 큰 값은 무엇인가?

- 이 둘을 빼면 max+min-a-b가 되고 max-a ≥ 0, min-b ≤ 0이 된다.

- 따라서 max+min-a-b는 양수인지 음수인지 정확히 알 수 없다.

- 이 둘 중 더 큰 값은 max+min 또는 a+b이다.

 

우리가 구하고자 하는 답은 3가지 경우 중 최솟값을 찾는 것이다.

그러면 2가지 경우가 있는데

1. max+a, max+b, max+min 중 최솟값

2. max+a, max+b, a+b 중 최솟값

 

1번은 3가지 모두 max가 있기 때문에 max를 제외한 a, b, min을 비교하여 최솟값은 min. 즉, max+min이다.

2번은 max+a, a+b 그리고 max+b, a+b를 비교한다.

2-1. max+a, a+b는 a가 공통으로 있기 때문에 max와 b를 비교하면 b가 더 작으므로 a+b가 max+a보다 작다.

2-2. max+b, a+b는 b가 공통으로 있기 때문에 max와 a를 비교하면 a가 더 작으므로 a+b가 max+b보다 작다.

따라서 2번은 a+b가 max+a와 max+b보다 작기 때문에 a+b가 최솟값이다.

 

- 여기서 알 수 있는 점은 최솟값은 3번의 경우인 [max, min], [a, b]에서 나온다.

- 즉, max, min, a, b에서 2개씩 묶어 2개의 값을 더한 값이 최댓값들 중 최솟값은 max+min 또는 a+b이다.

- 그래서 이 문제를 구하기 위해서는 2개씩 묶을 때 최댓값과 최솟값을 묶는다.

 

- 만약 n개의 수가 있다고 하자. max, min, a1, a2,... , an-2

- [max, min]을 묶으면 a1,..., an-2가 남는데, 남은 n-2개의 수 중에서도 최대, 최소가 존재할 것이다.

- 이런 식으로 최대와 최소를 묶으면 원하는 답을 구할 수 있다.

 

코드 해설)

- n개의 수를 입력하여 리스트 내에 저장 후, 오름차순으로 정렬한다.

- for 문을 이용해 index가 0과 n-1, 1과 n-2,... , (n/2-1)과 n/2의 각각 2개의 원소를 더한다.

- 이미 위의 3번 경우를 만족하기 때문에 더한 값의 최댓값만 구하면 된다.

- 초기 최댓값은 0으로 정하고 이보다 크면 갱신해 주어 최댓값을 구한다.

 


Q) 특정한 문자열로 시작하는 단어들

- 자연수 n, k. 문자열 string을 입력

- n개의 문자열을 입력하여 string으로 시작하는 단어들 중 사전순으로 정렬하여 k번째 문자열을 출력하라.

 

n,k,string=input().split()
n,k=int(n),int(k)
arr=[]

for _ in range(n):
    input_string=input()
    if len(string)<=len(input_string):
        if input_string[0:len(string)]==string: arr.append(input_string)

arr.sort()
print(arr[k-1])

 

결과

>> 5 2 ba
>> apple
>> banana
>> car
>> bar
>> band
band

 

- 'ba'로 시작하는 단어는 'banana', 'bar', 'band'이고, 정렬하면 'banana', 'band', 'bar'이 된다.

- 2번째 단어는 'band'이다.

 

풀이)

- string으로 시작하는 문자열인지 확인하기 위해서는 2가지 조건을 만족해야 한다.

1. string의 길이가 input_string의 길이보다 작거나 같아야 한다.

2. input_string의 첫 부분string과 같으면 리스트 arr에 삽입한다.

※ 1번 조건을 제외해도 오류는 발생하지 않는다. 파이썬의 slicing은 index를 초과하더라도 오류가 발생하지 않는 특성이지만 문제 풀이상 필요한 조건이라 생각하여 추가했다.

- 조건에 맞는 문자열들의 리스트인 arr을 정렬하여 k번째 값을 출력한다.

 


Q) 중앙값 출력

- 자연수 n을 입력. n개의 숫자를 입력

- 숫자들을 읽으면서 1번째부터 n번째까지 입력받은 숫자들의 중앙값을 출력하라

- 중앙값은 오름차순으로 정렬할 때 중앙에 위치한 숫자이다.

- 짝수개이면 중앙에 위치한 두 값의 평균을 중앙값이라 한다. (소수점은 버리고 정수 형태로 출력.)

- 예를 들어, n=5이고 1, 6, 7, 5, 3이라 하면

- n=1일 때, 1

- n=2일 때, 1, 6의 중앙값 3

- n=3일 때, 1, 6, 7의 중앙값 6

- n=4일 때, 1, 6, 7, 5의 중앙값 5 (5와 6의 평균)

- n=5일 때, 1, 6, 7, 5, 3의 중앙값 5

 

n=int(input())
arr=list(map(int,input().split()))
ans=[]

for i in range(n):
    ans.append(arr[i])
    ans.sort()
    if i%2==0: print(ans[i//2],end=' ')
    else: print((ans[i//2]+ans[i//2+1])//2,end=' ')

 

결과

>> 5
>> 1 6 7 5 3
1 3 6 5 5

 

풀이)

- 숫자들을 입력하여 새로운 리스트인 ans에 삽입한다.

- ans를 정렬하여 입력한 숫자가 홀수 번째 i라 하면 ans의 i//2번째 수를 출력한다.

- 짝수 번째 j라 하면 ans의 j//2번째와 j//2+1번째를 더해 2를 나눈 수를 출력한다.

※ 리스트는 0번부터 시작하기 때문에 코드에서는 짝수번째가 홀수번째가 되고 홀수번째가 짝수번째가 된다.