{ }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()·표준 입력으로 들어가요(실행 중에 묻지 않아요).

$ 준비됐어요

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

다른 언어로는?언어별 풀이 보기 · 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부터 돌면 저절로 알파벳 순이에요.
크레이콘은 사전()의 값으로 목록을 넣고(만약 (!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].잇기(" "));}