題目背景: Gorellians 每年重新定義英文字母順序,給定一個排列 s(26 大寫字母的排列)和 n 個單詞,按 s 定義的字典序輸出單詞。n ≤ 20,單詞長度 ≤ 30。
Order[c] = c 在 s 中的位置,將自定義字母序轉換為整數順序。Order 映射後的字符順序建立子節點。flag(單詞結束計數)和 next[26] 指針。Order[26]。insert 插入字典樹。print 遞歸遍歷輸出。#include <cstdio>
#include <cstring>
typedef struct nn {
int flag;
struct nn *next[26];
} node;
node *root;
node *builde() {
node *p = new node;
for (int i = 0; i < 26; i++) p->next[i] = NULL;
p->flag = 0; return p;
}
char str[50], s[50];
int Order[50];
void insert() {
node *p = root;
for (int i = 0; str[i]; i++) {
int j = Order[str[i] - 'A'];
if (!p->next[j]) p->next[j] = builde();
p = p->next[j];
}
p->flag++;
}
void print(node *p, int len) {
if (p->flag) {
for (int i = 1; i <= p->flag; i++) printf("%s\n", str);
}
for (int i = 0; i < 26; i++)
if (p->next[i]) {
str[len] = s[i];
str[len+1] = '\0';
print(p->next[i], len+1);
}
}
int main() {
int t = 0, n;
while (scanf("%d", &n) && n) {
scanf("%s", s);
for (int i = 0; i < 26; i++) Order[s[i] - 'A'] = i;
root = builde();
while (n--) { scanf("%s", str); insert(); }
printf("year %d\n", ++t);
print(root, 0);
}
return 0;
}
插入單詞總長度 L ≤ 600,構建字典樹 O(L)。遍歷輸出 O(L)。空間 O(L)。極高效。
也可直接用 std::sort 配合自定義比較器,但字典樹方法更能體現「字典序」本質,且易於擴展(如前綴查詢)。