{ }codelper
分组按键排序P0066

按首字母分组

给出一行由单个空格分隔的小写英文单词。
把首字母相同的单词分为一组。
对出现过的每个首字母,按字母顺序(从 a 开始)每行输出 "字母: 单词 单词 …"。
组内单词按输入中出现的顺序书写,同一单词出现多次就全部写出。

输入
单词数 1 到 1000,每个单词为 1 到 12 个小写英文字母
输出
出现过的首字母个数的行。
每行为字母、冒号(:),然后每个单词前加一个空格
样例 1 · stdin
banana apple cherry avocado blueberry apple
stdout
a: apple avocado apple
b: banana blueberry
c: cherry
main.py
输入(stdin)

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

$ 就绪

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

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

分组就是“键不存在就先放入空列表,再往该列表里添加”。
各语言的一行写法不同:Python defaultdict(list) 或 groups.setdefault(c, []).append(w),Java computeIfAbsent(c, k -> new ArrayList<>()).add(w),C# 用 TryGetValue,没有就放入新 List,C++ groups[c].push_back(w)([] 会替你创建空 vector),JS 用 Map 先 has 再 set(c, [])。
陷阱:Python groups.get(c, []).append(w)、JS (groups.get(c) ?? []).push(w)、Java getOrDefault(c, new ArrayList<>()).add(w) 只是加到新列表里,并没有存进字典,所以分组一直是空的。
第二个陷阱是输出顺序:Python dict・JS Map 按首次出现的字母顺序遍历,Java HashMap 不保证顺序,所以要对键排序,或用 TreeMap・SortedDictionary・std::map。
C 没有字典,但首字母只有 26 种,用每个字母一格的固定表(head[26])就够了,从 a 开始遍历自然就是字母顺序。
Craykon 把列表作为 字典() 的值(如果 (!groups.包含(c)) { groups[c] = []; } 之后 groups[c].添加(w)),再用 letters = groups.键列表; letters.排序(); 排好顺序。

Pythonmain.py · 7 行
from collections import defaultdict groups = defaultdict(list)for w in input().split():    groups[w[0]].append(w)for letter in sorted(groups):    print(f"{letter}: {' '.join(groups[letter])}")
JavaScriptmain.js · 8 行
const words = require("fs").readFileSync(0, "utf8").trim().split(/\s+/);const groups = new Map();for (const w of words) {  if (!groups.has(w[0])) groups.set(w[0], []);  groups.get(w[0]).push(w);}const letters = [...groups.keys()].sort();console.log(letters.map((c) => `${c}: ${groups.get(c).join(" ")}`).join("\n"));
TypeScriptmain.ts · 9 行
import { readFileSync } from "node:fs";const words: string[] = readFileSync(0, "utf8").trim().split(/\s+/);const groups = new Map<string, string[]>();for (const w of words) {  if (!groups.has(w[0])) groups.set(w[0], []);  groups.get(w[0])!.push(w);}const letters: string[] = [...groups.keys()].sort();console.log(letters.map((c) => `${c}: ${groups.get(c)!.join(" ")}`).join("\n"));
JavaMain.java · 20 行
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.List;import java.util.Map;import java.util.TreeMap; public class Main {    public static void main(String[] args) throws IOException {        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));        Map<Character, List<String>> groups = new TreeMap<>();        for (String w : in.readLine().trim().split(" "))            groups.computeIfAbsent(w.charAt(0), k -> new ArrayList<>()).add(w);        StringBuilder out = new StringBuilder();        for (Map.Entry<Character, List<String>> e : groups.entrySet())            out.append(e.getKey()).append(": ").append(String.join(" ", e.getValue())).append('\n');        System.out.print(out);    }}
C#Main.cs · 20 行
using System;using System.Collections.Generic; class Program{    static void Main()    {        var groups = new SortedDictionary<char, List<string>>();        foreach (string w in Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries))        {            if (!groups.TryGetValue(w[0], out var list))            {                list = new List<string>();                groups[w[0]] = list;            }            list.Add(w);        }        foreach (var kv in groups) Console.WriteLine($"{kv.Key}: {string.Join(" ", kv.Value)}");    }}
C++main.cpp · 15 行
#include <iostream>#include <map>#include <string>#include <vector> int main() {    std::map<char, std::vector<std::string>> groups;    std::string w;    while (std::cin >> w) groups[w[0]].push_back(w); // 없는 열쇠는 빈 vector가 생긴다    for (const auto& [letter, list] : groups) {        std::cout << letter << ':';        for (const auto& x : list) std::cout << ' ' << x;        std::cout << '\n';    }}
Cmain.c · 26 行
#include <stdio.h> /* C에는 사전이 없다: 첫 글자가 a~z 26가지뿐이니 글자마다 칸이 있는 고정 표를 쓴다 */static char words[1000][13];static int next_in_group[1000]; int main(void) {    int head[26], tail[26];    for (int c = 0; c < 26; c++) head[c] = tail[c] = -1;    int n = 0;    while (scanf("%12s", words[n]) == 1) {        int c = words[n][0] - 'a';        next_in_group[n] = -1;        if (head[c] < 0) head[c] = n;        else next_in_group[tail[c]] = n;        tail[c] = n;        n++;    }    for (int c = 0; c < 26; c++) {        if (head[c] < 0) continue;        printf("%c:", 'a' + c);        for (int i = head[c]; i >= 0; i = next_in_group[i]) printf(" %s", words[i]);        printf("\n");    }    return 0;}
Craykonmain.cray · 17 行
words = 控制台.读行().去空白().分割();groups = 字典();遍历 (w 在 words){    c = w[0];    如果 (!groups.包含(c))    {        groups[c] = [];    }    groups[c].添加(w);}letters = groups.键列表;letters.排序();遍历 (c 在 letters){    控制台.输出(c + ": " + groups[c].连接(" "));}