{ }codelper
목록 정렬P0320

수 크기 순서와 사전 순서

정수 n개를 두 가지 순서로 늘어놓는다. 첫째는 수 크기 순서로, 작은 수부터 차례로 놓는다. 둘째는 사전 순서로, 수를 입력에 적힌 그대로의 문자열로 보고 견준다. 두 문자열은 앞에서부터 한 글자씩 견주어 처음으로 다른 글자가 더 앞선 쪽이 먼저이고, 글자의 차례는 -, 0, 1, …, 9이다. 한 문자열이 다른 문자열의 앞부분과 똑같으면 짧은 쪽이 먼저이다. 첫 줄에 n이, 둘째 줄에 정수 n개가 빈칸 하나씩 띄워 주어진다. 첫 줄에 수 크기 순서로, 둘째 줄에 사전 순서로 n개를 빈칸 하나씩 띄워 출력하라. 같은 수는 나온 만큼 모두 출력한다. 셋째 줄에는 두 줄에서 같은 자리에 같은 수가 놓인 자리의 개수를 출력하라.

입력
1 ≤ n ≤ 1,000.
정수는 -2,000,000,000 이상 2,000,000,000 이하이고, 쉼표 없이 숫자만으로 주어진다.
음수는 맨 앞에 -가 붙고, + 기호나 필요 없는 0(007, -0)은 붙지 않는다
출력
세 줄: 수 크기 순서, 사전 순서, 같은 자리에 같은 수가 놓인 자리의 개수
예시 1 · stdin
6
10 9 -3 100 -20 9
stdout
-20 -3 9 9 10 100
-20 -3 10 100 9 9
2
예시 2 · stdin
2
2000000000 -2000000000
stdout
-2000000000 2000000000
-2000000000 2000000000
2
main.py
입력(stdin)

실행하면 이 줄들이 차례로 input()·표준 입력으로 들어가요(실행 중에 묻지 않아요).

$ 준비됐어요

코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.

다른 언어로는?언어별 풀이 보기 · 8개 언어 풀이

같은 정렬 도구가 무엇을 담았느냐에 따라 순서를 다르게 정해요.
Python sorted(tokens, key=int)는 수로 바꾼 값으로, sorted(tokens)는 문자열 그대로 견줘요.
Java Arrays.sort는 int[]면 수 크기, String[]이면 사전 순서이고, C++ std::sort도 vector<int>와 vector<string>에서 그렇게 달라요.
크레이콘 목록.정렬()도 수 목록은 수 크기, 문자열 목록은 사전 순서예요.
C qsort는 견주는 함수를 꼭 넘겨야 해서 수에는 (x > y) - (x < y), 문자열에는 strcmp를 써요.
C#은 Array.Sort(byNum)과 Array.Sort(byText, StringComparer.Ordinal)로, 문자열에는 글자 코드로 견주라고 알려 줘요(기본 비교는 문화권 규칙을 따라요.
-와 숫자뿐인 이 문제에서는 채점 환경에서 두 결과가 같지만, 글자 코드 순서를 바란다고 밝혀 두는 것이 안전해요).
JS·TS만 거꾸로예요: 아무것도 넘기지 않은 sort()가 사전 순서이고, 수 크기 순서는 sort((x, y) => x - y)로 견주는 함수를 넘겨야 해요.
함정 넷: ① 수로 바꾸지 않거나 견주는 방법을 알려 주지 않으면 첫 줄이 사전 순서가 돼요(예시 1의 첫 줄이 -20 -3 10 100 9 9로).
JS nums.sort()는 수 배열이어도 문자열로 바꿔 견주고, Python에서 key=int를 빠뜨리거나 크레이콘에서 수로변환 없이 문자열 목록을 정렬()해도 그래요.
② 제자리 정렬은 복사본을 만들지 않아요.
JS sort는 그 배열을 정렬해 그대로 돌려주므로 const byNum = nums.sort(...)와 const byText = nums.sort()는 같은 배열 하나예요.
Python by_num = tokens도 복사가 아니에요.
두 줄이 똑같아지고 셋째 줄이 n이 돼요(예시 1이 6으로).
JS [...tokens], Python sorted, Java clone(), 크레이콘 부분목록(0, n)으로 따로 만들어요.
③ Python by_num = tokens.sort(key=int)는 정렬된 목록이 아니라 None을 담아서, 그것을 쓰는 줄에서 TypeError로 멈춰요.
④ 견주는 함수를 빼기로 쓰는 C return x - y;와 Java (x, y) -> x - y는 2000000000 - (-2000000000)이 int 범위를 넘쳐 음수가 돼서, 큰 수가 앞에 놓여요(예시 2의 첫 줄이 2000000000 -2000000000으로).
C는 (x > y) - (x < y), Java는 Integer.compare(x, y)를 써요.
JS의 x - y는 수가 실수라 이 범위에서 넘치지 않아요.

Pythonmain.py · 12 줄
n = int(input())tokens = input().split() # sorted는 새 목록을 돌려주고 원래 목록은 그대로 둔다by_num = sorted(tokens, key=int)  # 수로 바꾼 값을 기준으로: 수 크기 순서by_text = sorted(tokens)          # 문자열 그대로: 사전 순서 same = sum(1 for x, y in zip(by_num, by_text) if x == y) print(*by_num)print(*by_text)print(same)
JavaScriptmain.js · 18 줄
const lines = require("fs").readFileSync(0, "utf8").split("\n");const n = Number(lines[0]);const tokens = lines[1].trim().split(/\s+/); // sort는 그 배열 자체를 정렬하므로, 순서마다 배열을 따로 만든다// 수 크기 순서는 견주는 함수를 꼭 넘겨야 한다const byNum = tokens.map(Number).sort((x, y) => x - y);// 아무것도 넘기지 않은 sort()는 문자열로 견준다: 사전 순서const byText = [...tokens].sort(); let same = 0;for (let i = 0; i < n; i++) {  if (byNum[i] === Number(byText[i])) same++;} console.log(byNum.join(" "));console.log(byText.join(" "));console.log(same);
TypeScriptmain.ts · 19 줄
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const n: number = Number(lines[0]);const tokens: string[] = lines[1].trim().split(/\s+/); // sort는 그 배열 자체를 정렬하므로, 순서마다 배열을 따로 만든다// 수 크기 순서는 견주는 함수를 꼭 넘겨야 한다const byNum: number[] = tokens.map(Number).sort((x: number, y: number) => x - y);// 아무것도 넘기지 않은 sort()는 문자열로 견준다: 사전 순서const byText: string[] = [...tokens].sort(); let same: number = 0;for (let i = 0; i < n; i++) {  if (byNum[i] === Number(byText[i])) same++;} console.log(byNum.join(" "));console.log(byText.join(" "));console.log(same);
JavaMain.java · 37 줄
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.Arrays; public class Main {    public static void main(String[] args) throws IOException {        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));        int n = Integer.parseInt(in.readLine().trim());        String[] tokens = in.readLine().trim().split(" +");         // int 배열을 정렬하면 수 크기 순서        int[] byNum = new int[n];        for (int i = 0; i < n; i++) byNum[i] = Integer.parseInt(tokens[i]);        Arrays.sort(byNum);         // String 배열을 정렬하면 사전 순서. clone으로 복사본을 만들어 정렬한다        String[] byText = tokens.clone();        Arrays.sort(byText);         int same = 0;        StringBuilder numLine = new StringBuilder();        StringBuilder textLine = new StringBuilder();        for (int i = 0; i < n; i++) {            if (byNum[i] == Integer.parseInt(byText[i])) same++;            if (i > 0) {                numLine.append(' ');                textLine.append(' ');            }            numLine.append(byNum[i]);            textLine.append(byText[i]);        }        System.out.println(numLine);        System.out.println(textLine);        System.out.println(same);    }}
C#Main.cs · 28 줄
using System; class Program{    static void Main()    {        int n = int.Parse(Console.ReadLine().Trim());        string[] tokens = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries);         // int 배열을 정렬하면 수 크기 순서        int[] byNum = Array.ConvertAll(tokens, int.Parse);        Array.Sort(byNum);         // 문자열은 StringComparer.Ordinal을 넘겨 글자 코드 순서(사전 순서)로 정렬한다        string[] byText = (string[])tokens.Clone();        Array.Sort(byText, StringComparer.Ordinal);         int same = 0;        for (int i = 0; i < n; i++)        {            if (byNum[i] == int.Parse(byText[i])) same++;        }         Console.WriteLine(string.Join(" ", byNum));        Console.WriteLine(string.Join(" ", byText));        Console.WriteLine(same);    }}
C++main.cpp · 28 줄
#include <algorithm>#include <iostream>#include <string>#include <vector> int main() {    int n;    std::cin >> n;    std::vector<std::string> byText(n);    std::vector<int> byNum(n);    for (int i = 0; i < n; i++) {        std::cin >> byText[i];        byNum[i] = std::stoi(byText[i]);    }     // 같은 std::sort지만 int는 수 크기로, std::string은 사전 순서로 견준다    std::sort(byNum.begin(), byNum.end());    std::sort(byText.begin(), byText.end());     int same = 0;    for (int i = 0; i < n; i++) {        if (byNum[i] == std::stoi(byText[i])) same++;    }     for (int i = 0; i < n; i++) std::cout << byNum[i] << (i + 1 < n ? ' ' : '\n');    for (int i = 0; i < n; i++) std::cout << byText[i] << (i + 1 < n ? ' ' : '\n');    std::cout << same << '\n';}
Cmain.c · 39 줄
#include <stdio.h>#include <stdlib.h>#include <string.h> /* 수 크기로 견준다. 빼기(x - y)는 int 범위를 넘칠 수 있어서 쓰지 않는다 */static int by_num(const void *a, const void *b) {    int x = *(const int *)a, y = *(const int *)b;    return (x > y) - (x < y);} /* 문자열로 견준다. strcmp가 바로 사전 순서다 */static int by_text(const void *a, const void *b) {    return strcmp((const char *)a, (const char *)b);} int main(void) {    int n;    static int nums[1000];    static char texts[1000][12]; /* "-2000000000"은 11글자, 끝 표시까지 12칸 */    scanf("%d", &n);    for (int i = 0; i < n; i++) {        scanf("%11s", texts[i]);        nums[i] = atoi(texts[i]);    }     /* qsort는 견주는 함수를 받는다. 배열마다 다른 함수를 넘긴다 */    qsort(nums, n, sizeof nums[0], by_num);    qsort(texts, n, sizeof texts[0], by_text);     int same = 0;    for (int i = 0; i < n; i++) {        if (nums[i] == atoi(texts[i])) same++;    }     for (int i = 0; i < n; i++) printf("%d%c", nums[i], i + 1 < n ? ' ' : '\n');    for (int i = 0; i < n; i++) printf("%s%c", texts[i], i + 1 < n ? ' ' : '\n');    printf("%d\n", same);    return 0;}
Craykonmain.cray · 27 줄
n = 콘솔.줄읽기().수로변환();tokens = 콘솔.줄읽기().공백제거().나누기(); // 정렬()은 그 목록 자체를 정렬한다. 수 목록은 수 크기 순서가 된다byNum = [];각각 (t 에서 tokens){    byNum.넣기(t.수로변환());}byNum.정렬(); // 문자열 목록은 사전 순서가 된다. 부분목록으로 복사본을 만들어 정렬한다byText = tokens.부분목록(0, n);byText.정렬(); same = 0;반복 (i = 0; i < n; i++){    만약 (byNum[i] == byText[i].수로변환())    {        same++;    }} 콘솔.쓰기(byNum.잇기(" "));콘솔.쓰기(byText.잇기(" "));콘솔.쓰기(same);