n = int(input())words = input().split()# 글자를 정렬한 문자열이 같으면 같은 묶음이다(eat, tea → "aet")groups = {}for w in words: key = "".join(sorted(w)) # sorted(w)는 목록이라 사전 열쇠가 될 수 없다 groups.setdefault(key, []).append(w)result = [sorted(g) for g in groups.values()]result.sort(key=lambda g: (-len(g), g[0])) # 큰 묶음 먼저, 같으면 첫 낱말 사전 순for g in result: print(f"{len(g)}: {' '.join(g)}")
JavaScriptmain.js · 14 行
const [n, ...words] = require("fs").readFileSync(0, "utf8").trim().split(/\s+/);// 글자를 정렬한 문자열이 같으면 같은 묶음이다(eat, tea → "aet")const groups = new Map();for (const w of words) { const key = [...w].sort().join(""); // 배열 그대로는 열쇠로 못 쓴다(배열은 같은 객체일 때만 같다) if (!groups.has(key)) groups.set(key, []); groups.get(key).push(w);}const result = [...groups.values()].map((g) => g.sort());const cmp = (a, b) => (a < b ? -1 : a > b ? 1 : 0);result.sort((a, b) => b.length - a.length || cmp(a[0], b[0])); // 큰 묶음 먼저, 같으면 첫 낱말console.log(result.map((g) => `${g.length}: ${g.join(" ")}`).join("\n"));
TypeScriptmain.ts · 16 行
import { readFileSync } from "node:fs";const [, ...words]: string[] = readFileSync(0, "utf8").trim().split(/\s+/);// 글자를 정렬한 문자열이 같으면 같은 묶음이다(eat, tea → "aet")const groups = new Map<string, string[]>();for (const w of words) { const key = [...w].sort().join(""); // 배열 그대로는 열쇠로 못 쓴다(배열은 같은 객체일 때만 같다) const g = groups.get(key); if (g) g.push(w); else groups.set(key, [w]);}const result: string[][] = [...groups.values()].map((g) => g.sort());const cmp = (a: string, b: string): number => (a < b ? -1 : a > b ? 1 : 0);result.sort((a, b) => b.length - a.length || cmp(a[0], b[0])); // 큰 묶음 먼저, 같으면 첫 낱말console.log(result.map((g) => `${g.length}: ${g.join(" ")}`).join("\n"));
JavaMain.java · 30 行
import java.io.*;import java.util.*;public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); br.readLine(); String[] words = br.readLine().trim().split(" "); // 글자를 정렬한 문자열이 같으면 같은 묶음이다(eat, tea → "aet") Map<String, List<String>> groups = new HashMap<>(); for (String w : words) { char[] c = w.toCharArray(); Arrays.sort(c); String key = new String(c); // char[] 그대로는 열쇠가 안 된다(배열은 내용이 아니라 객체로 비교) groups.computeIfAbsent(key, k -> new ArrayList<>()).add(w); } List<List<String>> result = new ArrayList<>(); for (List<String> g : groups.values()) { Collections.sort(g); result.add(g); } result.sort(Comparator.<List<String>>comparingInt(g -> -g.size()).thenComparing(g -> g.get(0))); StringBuilder out = new StringBuilder(); for (List<String> g : result) out.append(g.size()).append(": ").append(String.join(" ", g)).append('\n'); System.out.print(out); }}
C#Main.cs · 34 行
using System;using System.Collections.Generic;using System.Linq;class Program{ static void Main() { Console.ReadLine(); string[] words = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); // 글자를 정렬한 문자열이 같으면 같은 묶음이다(eat, tea → "aet") var groups = new Dictionary<string, List<string>>(); foreach (string w in words) { char[] c = w.ToCharArray(); Array.Sort(c); string key = new string(c); // char[] 그대로는 열쇠가 안 된다(배열은 객체로 비교) if (!groups.TryGetValue(key, out var list)) { list = new List<string>(); groups[key] = list; } list.Add(w); } // 문자열은 Ordinal로 비교한다(기본 비교는 문화권 규칙을 따른다) var result = groups.Values .Select(g => g.OrderBy(w => w, StringComparer.Ordinal).ToList()) .OrderByDescending(g => g.Count) .ThenBy(g => g[0], StringComparer.Ordinal); foreach (var g in result) Console.WriteLine($"{g.Count}: {string.Join(" ", g)}"); }}
C++main.cpp · 35 行
#include <algorithm>#include <iostream>#include <map>#include <string>#include <vector>int main() { int n; std::cin >> n; // 글자를 정렬한 문자열이 같으면 같은 묶음이다(eat, tea → "aet") std::map<std::string, std::vector<std::string>> groups; for (int i = 0; i < n; i++) { std::string w; std::cin >> w; std::string key = w; std::sort(key.begin(), key.end()); // std::string은 값이라 정렬한 복사본이 곧 열쇠 groups[key].push_back(w); // []가 없으면 빈 vector를 만들어 준다 } std::vector<std::vector<std::string>> result; for (auto& [key, g] : groups) { std::sort(g.begin(), g.end()); result.push_back(g); } std::sort(result.begin(), result.end(), [](const auto& a, const auto& b) { if (a.size() != b.size()) return a.size() > b.size(); // 큰 묶음 먼저 return a[0] < b[0]; // 같으면 첫 낱말 사전 순 }); for (const auto& g : result) { std::cout << g.size() << ":"; for (const auto& w : g) std::cout << " " << w; std::cout << "\n"; }}
Cmain.c · 55 行
#include <stdio.h>#include <stdlib.h>#include <string.h>/* C에는 사전이 없다: (정렬한 글자, 낱말) 차례로 정렬하면 같은 묶음이 붙어 나오고 묶음 안도 사전 순이 된다 */typedef struct { char key[11]; char word[11];} Item;typedef struct { int start, size; /* items[start] ~ items[start + size - 1] */} Group;static Item items[5000];static Group groups[5000];static int cmp_char(const void *a, const void *b) { return *(const char *)a - *(const char *)b; }static int cmp_item(const void *a, const void *b) { const Item *x = a, *y = b; int c = strcmp(x->key, y->key); return c != 0 ? c : strcmp(x->word, y->word);}static int cmp_group(const void *a, const void *b) { const Group *x = a, *y = b; if (x->size != y->size) return y->size - x->size; /* 큰 묶음 먼저 */ return strcmp(items[x->start].word, items[y->start].word); /* 같으면 첫 낱말 */}int main(void) { int n; scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%10s", items[i].word); strcpy(items[i].key, items[i].word); qsort(items[i].key, strlen(items[i].key), 1, cmp_char); } qsort(items, n, sizeof(Item), cmp_item); int g = 0; for (int i = 0; i < n; i++) { if (i == 0 || strcmp(items[i].key, items[i - 1].key) != 0) groups[g++] = (Group){i, 0}; groups[g - 1].size++; } qsort(groups, g, sizeof(Group), cmp_group); for (int i = 0; i < g; i++) { printf("%d:", groups[i].size); for (int j = 0; j < groups[i].size; j++) printf(" %s", items[groups[i].start + j].word); printf("\n"); } return 0;}
Craykonmain.cray · 52 行
コンソール.行読み();words = コンソール.行読み().空白除去().分ける();// 글자를 정렬한 문자열이 같으면 같은 묶음이다(eat, tea → "aet")groups = 辞書();それぞれ (w の中 words){ key = 글자정렬(w); もし (!groups.含む(key)) { groups[key] = []; } groups[key].追加(w);}keys = groups.キー一覧;それぞれ (key の中 keys){ groups[key].並べ替え();}keys.並べ替え(큰묶음먼저);それぞれ (key の中 keys){ g = groups[key]; コンソール.書く(g.個数 + ": " + g.つなぐ(" "));}// 낱말의 글자를 하나씩 목록에 담아 정렬한 뒤 다시 잇는다글자정렬(w){ c = []; 繰り返す (i = 0; i < w.長さ; i++) { c.追加(w[i]); } c.並べ替え(); 返す c.つなぐ("");}// 큰 묶음 먼저, 크기가 같으면 첫 낱말이 사전 순으로 앞선 묶음 먼저큰묶음먼저(앞, 뒤){ もし (groups[앞].個数 != groups[뒤].個数) { 返す groups[뒤].個数 - groups[앞].個数; } もし (groups[앞][0] < groups[뒤][0]) { 返す -1; } 返す 1;}