더 나아가기 · 17
정렬
작은 것부터, 큰 것부터, 내가 정한 기준으로 늘어놓기.
정렬은 값을 차례대로 늘어놓는 거예요.
아래 예제는 수를 작은 것부터·큰 것부터 늘어놓고, 단어를 글자 순과 "짧은 것부터" 순으로 늘어놓아요.
nums = list(map(int, input().split()))words = input().split()print(*sorted(nums))print(*sorted(nums, reverse=True))print(*sorted(words))print(*sorted(words, key=lambda w: (len(w), w)))const [line1, line2] = require("fs").readFileSync(0, "utf8").trim().split("\n");const nums = line1.trim().split(/\s+/).map(Number);const words = line2.trim().split(/\s+/);console.log([...nums].sort((a, b) => a - b).join(" "));console.log([...nums].sort((a, b) => b - a).join(" "));console.log([...words].sort().join(" "));const byLength = (a, b) => a.length - b.length || (a < b ? -1 : a > b ? 1 : 0);console.log([...words].sort(byLength).join(" "));import { readFileSync } from "node:fs";const [line1, line2]: string[] = readFileSync(0, "utf8").trim().split("\n");const nums: number[] = line1.trim().split(/\s+/).map(Number);const words: string[] = line2.trim().split(/\s+/);console.log([...nums].sort((a, b) => a - b).join(" "));console.log([...nums].sort((a, b) => b - a).join(" "));console.log([...words].sort().join(" "));const byLength = (a: string, b: string): number => a.length - b.length || (a < b ? -1 : a > b ? 1 : 0);console.log([...words].sort(byLength).join(" "));import java.util.*;import java.util.stream.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int[] nums = Arrays.stream(sc.nextLine().trim().split("\\s+")).mapToInt(Integer::parseInt).toArray(); String[] words = sc.nextLine().trim().split("\\s+"); Arrays.sort(nums); System.out.println(Arrays.stream(nums).mapToObj(String::valueOf).collect(Collectors.joining(" "))); Integer[] boxed = Arrays.stream(nums).boxed().toArray(Integer[]::new); Arrays.sort(boxed, Comparator.reverseOrder()); System.out.println(Arrays.stream(boxed).map(String::valueOf).collect(Collectors.joining(" "))); String[] abc = words.clone(); Arrays.sort(abc); System.out.println(String.join(" ", abc)); Arrays.sort(words, Comparator.comparingInt(String::length).thenComparing(Comparator.naturalOrder())); System.out.println(String.join(" ", words)); }}using System;using System.Linq; class Program{ static void Main() { int[] nums = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray(); string[] words = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); Array.Sort(nums); Console.WriteLine(string.Join(" ", nums)); Console.WriteLine(string.Join(" ", nums.OrderByDescending(x => x))); Console.WriteLine(string.Join(" ", words.OrderBy(w => w, StringComparer.Ordinal))); var byLength = words.OrderBy(w => w.Length).ThenBy(w => w, StringComparer.Ordinal); Console.WriteLine(string.Join(" ", byLength)); }}#include <algorithm>#include <functional>#include <iostream>#include <sstream>#include <string>#include <vector> template <typename T>void print(const std::vector<T>& v) { for (size_t i = 0; i < v.size(); i++) std::cout << (i > 0 ? " " : "") << v[i]; std::cout << '\n';} int main() { std::string line; std::getline(std::cin, line); std::istringstream in1(line); std::vector<int> nums; for (int x; in1 >> x;) nums.push_back(x); std::getline(std::cin, line); std::istringstream in2(line); std::vector<std::string> words; for (std::string w; in2 >> w;) words.push_back(w); std::sort(nums.begin(), nums.end()); print(nums); std::sort(nums.begin(), nums.end(), std::greater<int>()); print(nums); std::sort(words.begin(), words.end()); print(words); std::sort(words.begin(), words.end(), [](const std::string& a, const std::string& b) { if (a.size() != b.size()) return a.size() < b.size(); return a < b; }); print(words);}#include <stdio.h>#include <stdlib.h>#include <string.h> int asc(const void *a, const void *b) { int x = *(const int *)a, y = *(const int *)b; return (x > y) - (x < y);}int desc(const void *a, const void *b) { return asc(b, a); }int abc(const void *a, const void *b) { return strcmp(*(char *const *)a, *(char *const *)b); }int by_length(const void *a, const void *b) { const char *s = *(char *const *)a, *t = *(char *const *)b; size_t ls = strlen(s), lt = strlen(t); if (ls != lt) return ls < lt ? -1 : 1; return strcmp(s, t);} int main(void) { char line[4096], wline[4096], *words[1000]; int nums[1000], n = 0, m = 0; fgets(line, sizeof line, stdin); fgets(wline, sizeof wline, stdin); for (char *p = strtok(line, " \r\n"); p; p = strtok(NULL, " \r\n")) nums[n++] = atoi(p); for (char *p = strtok(wline, " \r\n"); p; p = strtok(NULL, " \r\n")) words[m++] = p; qsort(nums, n, sizeof nums[0], asc); for (int i = 0; i < n; i++) printf(i > 0 ? " %d" : "%d", nums[i]); printf("\n"); qsort(nums, n, sizeof nums[0], desc); for (int i = 0; i < n; i++) printf(i > 0 ? " %d" : "%d", nums[i]); printf("\n"); qsort(words, m, sizeof words[0], abc); for (int i = 0; i < m; i++) printf(i > 0 ? " %s" : "%s", words[i]); printf("\n"); qsort(words, m, sizeof words[0], by_length); for (int i = 0; i < m; i++) printf(i > 0 ? " %s" : "%s", words[i]); printf("\n"); return 0;}nums = 콘솔.수들읽기();words = 콘솔.줄읽기().나누기(); // 앞이 먼저면 음수, 뒤가 먼저면 양수큰것먼저(앞, 뒤){ 돌려주기 뒤 - 앞;} 짧은것먼저(앞, 뒤){ 만약 (앞.길이 != 뒤.길이) { 돌려주기 앞.길이 - 뒤.길이; } 만약 (앞 < 뒤) { 돌려주기 -1; } 만약 (앞 > 뒤) { 돌려주기 1; } 돌려주기 0;} nums.정렬();콘솔.쓰기(nums);nums.정렬(큰것먼저);콘솔.쓰기(nums);words.정렬();콘솔.쓰기(words);words.정렬(짧은것먼저);콘솔.쓰기(words);10 9 1 25 3 pear fig banana kiwi apple
1 3 9 10 25 25 10 9 3 1 apple banana fig kiwi pear fig kiwi pear apple banana
핵심
- 기본은 수는 크기 순, 문자열은 사전 순(글자 코드 순)이에요.
- 새 목록을 돌려주는 정렬과 제자리에서 바꾸는 정렬이 있어요.
Pythonsorted(nums)는 새 목록,nums.sort()는 제자리예요. - 기준을 주는 방법은 둘이에요.
열쇠 함수는 값마다 비교할 열쇠를 말해요(Pythonkey=lambda w: (len(w), w)는 "길이, 같으면 글자 순"). - 비교 함수는 두 값을 받아, 앞이 먼저면 음수, 같으면 0, 뒤가 먼저면 양수를 돌려줘요.
- 안정 정렬은 기준이 같은 값끼리 원래 차례를 지켜요.
안정이 아닌 정렬에서는 같을 때의 기준(길이가 같으면 글자 순)까지 비교 함수에 적어요.
언어별로 쓰는 법
| Python | sorted(nums)(새 목록), nums.sort()(제자리).큰 것부터 reverse=True, 기준은 key=lambda w: (len(w), w).안정적이에요 |
|---|---|
| JavaScript | arr.sort((a, b) => a - b) — 제자리.비교 함수가 없으면 수도 문자열로 비교해요. 여러 기준은 a.length - b.length || ....ES2019부터 안정적 |
| TypeScript | JavaScript와 같아요 |
| Java | Arrays.sort, Collections.sort.큰 것부터 Comparator.reverseOrder(), 기준은 Comparator.comparingInt(String::length).thenComparing(...).객체 배열과 Collections.sort는 안정적.int[]는 비교 함수를 받지 않아요 |
| C# | Array.Sort·List.Sort(제자리, 안정 약속 없음), LINQ OrderBy(...).ThenBy(...)·OrderByDescending(안정적) |
| C++ | std::sort(v.begin(), v.end()), 큰 것부터 std::greater<int>().비교 람다는 "앞이 먼저인가"를 bool로 돌려줘요.안정이 필요하면 std::stable_sort |
| C | qsort(a, n, sizeof a[0], cmp) — cmp는 두 포인터를 받아 음수·0·양수를 돌려줘요.안정 약속 없음 |
| Craykon | 목록.정렬()은 작은 것부터.목록.정렬(짧은것먼저)처럼 비교 함수 이름을 넘겨요.안정적이에요 |
자주 하는 실수
int[]에 비교 함수를 넘겼어요Java
int[] a = {3, 1, 2};
Arrays.sort(a, Comparator.reverseOrder());→ 컴파일 오류 — int[]용 sort는 비교 함수를 받지 않아요
예제처럼 Integer[]로 바꾸거나, 작은 것부터 정렬한 뒤 거꾸로 읽어요.
수를 비교 함수 없이 sort()했어요JavaScript · TypeScript
console.log([10, 9, 1].sort());→ [ 1, 10, 9 ] — 수를 문자열로 바꿔 비교해요
수는 꼭 (a, b) => a - b를 넘겨요.
nums = nums.sort()라고 썼어요Python
nums = [3, 1, 2]
nums = nums.sort()
print(nums)→ None — sort는 제자리에서 정렬하고 아무것도 돌려주지 않아요
nums.sort()만 쓰거나, nums = sorted(nums)로 써요.
언어마다 다른 점
C
C
qsort 비교 함수를 return a - b;로 쓰면 큰 음수와 큰 양수를 뺄 때 int가 넘쳐(예: -2000000000 - 2000000000) 부호가 뒤집히고 순서가 틀려요.(a > b) - (a < b)처럼 비교로 쓰세요.