{ }codelper
比较字符串大小写连接输出P0103

忽略大小写排序

第一行给出单词数 n,第二行给出用单个空格分隔的 n 个单词。
按忽略大小写的顺序排序这些单词,在一行中用单个空格分隔输出。
两个单词的先后这样决定:先把两者中的英文大写字母都变成小写,再按字符编码(ASCII)比较。
从第一个字符开始依次比较,第一个不同字符编码较小的在前。
如果一个单词与另一个单词的开头部分相同,较短的在前。
变成小写后相同的单词("Bob" 和 "bob")保持它们在输入中出现的顺序。
字符编码中数字 0~9 是 48~57,下划线 _ 是 95,小写 a~z 是 97~122,所以 "_x" 在 "alice" 前面。

输入
1 ≤ n ≤ 2000。
每个单词 1 到 20 个字符,只由英文大小写字母、数字和下划线(_)组成
输出
排序后的 n 个单词,用单个空格分隔,一行
样例 1 · stdin
6
bob Alice _x alice Bob x9
stdout
_x Alice alice bob Bob x9
样例 2 · stdin
4
ab a AB a_
stdout
a a_ ab AB
main.py
输入(stdin)

运行时这些行会依次作为 input()/标准输入传入(运行中不会等待输入)。

$ 就绪

请在电脑上打开以编写和运行代码。在手机上可以查看题目和题解。

其他语言怎么写?查看各语言题解 · 8 种语言题解

陷阱有三个。
第一,直接排序时所有大写字母(65~90)都排在小写字母(97~122)前面,于是 "Bob" 排在 "alice" 前面。
第二,转成大写再比较时,下划线 _(95)会跑到字母后面,与转成小写时的顺序不同。
Python key=str.upper、C# StringComparer.OrdinalIgnoreCase(文档说明等同于转成大写)就是这样。
Java compareToIgnoreCase·CASE_INSENSITIVE_ORDER 最后转成小写比较,与本题一致。
JS localeCompare 用的是人类语言规则而不是字符编码,_ 的位置不同,而且拼写相同时把小写放前面,也会打乱输入顺序。
第三,要让相同的单词保持输入顺序,必须是稳定排序。
Python sorted、JS·TS sort(ES2019 起)、Java List.sort、C# OrderBy 是稳定排序。
C# List.Sort·Array.Sort、C++ std::sort、C qsort 不保证稳定。
C++ 用 std::stable_sort,C 把输入顺序存进结构体,作为比较的最后一个依据。
Linux(glibc)的 qsort 通常碰巧保持顺序,所以有时也能通过,但在 macOS 上真的会打乱。
这不是保证,不能依赖。
连接用 Python " ".join(words)、JS·TS words.join(" ")、Java String.join(" ", words)、C# string.Join(" ", words);C·C++ 只在第一个单词前不输出空格。
Craykon 给 words.排序(byLower) 传一个返回 -1·0·1 的函数(相同的保持顺序),再用 words.连接(" ") 连接。

Pythonmain.py · 4 行
n = int(input())words = input().split()# sorted는 안정 정렬이라, 소문자로 같은 단어끼리는 들어온 차례를 지킨다print(" ".join(sorted(words, key=str.lower)))
JavaScriptmain.js · 9 行
const [first, second] = require("fs").readFileSync(0, "utf8").split("\n");const words = second.trim().split(" ");const byLower = (a, b) => {  const x = a.toLowerCase();  const y = b.toLowerCase();  return x < y ? -1 : x > y ? 1 : 0; // < 는 글자 코드 순(localeCompare 아님)};// Array.prototype.sort는 ES2019부터 안정 정렬이다console.log(words.sort(byLower).join(" "));
TypeScriptmain.ts · 10 行
import { readFileSync } from "node:fs";const [, second] = readFileSync(0, "utf8").split("\n");const words: string[] = second.trim().split(" ");const byLower = (a: string, b: string): number => {  const x: string = a.toLowerCase();  const y: string = b.toLowerCase();  return x < y ? -1 : x > y ? 1 : 0; // < 는 글자 코드 순(localeCompare 아님)};// Array.prototype.sort는 ES2019부터 안정 정렬이다console.log(words.sort(byLower).join(" "));
JavaMain.java · 18 行
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.Arrays;import java.util.Comparator;import java.util.List;import java.util.Locale; public class Main {    public static void main(String[] args) throws IOException {        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));        in.readLine();        List<String> words = Arrays.asList(in.readLine().trim().split(" "));        // List.sort(객체)는 안정 정렬(TimSort). 소문자로 바꾼 것을 글자 코드로 비교한다        words.sort(Comparator.comparing((String w) -> w.toLowerCase(Locale.ROOT)));        System.out.println(String.join(" ", words));    }}
C#Main.cs · 14 行
using System;using System.Linq; class Program{    static void Main()    {        Console.ReadLine();        string[] words = Console.ReadLine().Trim().Split(' ');        // OrderBy는 안정 정렬. Ordinal은 글자 코드 순(문화권 규칙 없이)        var sorted = words.OrderBy(w => w.ToLowerInvariant(), StringComparer.Ordinal);        Console.WriteLine(string.Join(" ", sorted));    }}
C++main.cpp · 22 行
#include <algorithm>#include <cctype>#include <iostream>#include <string>#include <vector> static std::string lower(std::string s) {    for (char& c : s) c = (char)std::tolower((unsigned char)c);    return s;} int main() {    int n;    std::cin >> n;    std::vector<std::string> words(n);    for (auto& w : words) std::cin >> w;    // std::sort는 안정 정렬이 아니다: 같은 것끼리 차례를 지키려면 stable_sort    std::stable_sort(words.begin(), words.end(),                     [](const std::string& a, const std::string& b) { return lower(a) < lower(b); });    for (int i = 0; i < n; i++) std::cout << (i ? " " : "") << words[i];    std::cout << '\n';}
Cmain.c · 31 行
#include <ctype.h>#include <stdio.h>#include <stdlib.h> struct Word {    char text[21];    int order; /* 들어온 차례: qsort는 안정 정렬이 아니라서 직접 비교에 넣는다 */}; static int by_lower(const void *pa, const void *pb) {    const struct Word *a = pa, *b = pb;    const unsigned char *x = (const unsigned char *)a->text, *y = (const unsigned char *)b->text;    while (*x && tolower(*x) == tolower(*y)) x++, y++;    int d = tolower(*x) - tolower(*y); /* 한쪽이 끝나면 '\0'(0)이라 짧은 쪽이 앞 */    if (d != 0) return d;    return a->order - b->order;} int main(void) {    static struct Word w[2000];    int n;    scanf("%d", &n);    for (int i = 0; i < n; i++) {        scanf("%20s", w[i].text);        w[i].order = i;    }    qsort(w, n, sizeof w[0], by_lower);    for (int i = 0; i < n; i++) printf(i ? " %s" : "%s", w[i].text);    printf("\n");    return 0;}
Craykonmain.cray · 21 行
n = 控制台.读行().转数字();words = 控制台.读行().分割();// 정렬(기준함수)는 같은 것끼리 들어온 차례를 지킨다words.排序(byLower);控制台.输出(words.连接(" ")); // 소문자로 바꾼 것을 글자 코드 순으로 비교byLower(앞, 뒤){    a = 앞.小写();    b = 뒤.小写();    如果 (a < b)    {        返回 -1;    }    如果 (a > b)    {        返回 1;    }    返回 0;}