字典树-trie
描述:将火星文翻译成英文。
反思:好久以前做的,现在又拿来写了个字典树,递归比非递归确实慢,一个小错误导致wa数次。
代码
#include <stdio.h>
#include <string.h>
#include <ctype.h>
struct Node {
Node *t[26];
char mar[13];
Node () {
for (int i=0; i<26; i++)
t[i] = NULL;
mar[0] = '\0'; //key '\0' 写成了 '/0'
}
};
Node *head;
void build(Node *p, char *c1, char *c2) {
if (*c1 == '\0') {
strcpy(p->mar, c2);
return;
}
int k = *c1-'a';
if (p->t[k] == NULL) {
p->t[k] = new Node;
}
build(p->t[k], c1+1, c2);
}
void find(Node *p, char *c1, char *c2) {
if (*c1 == '\0') {
if (p->mar[0] != '\0')
strcpy(c2, p->mar);
return;
}
int k = *c1-'a';
if (p->t[k] != NULL) {
find(p->t[k], c1+1, c2);
}
}
int main()
{
char c1[20], c2[20], c[3010];
// freopen("datain", "r", stdin);
// freopen("dataout", "w", stdout);
while (scanf("%s", c1) != EOF) {
head = new Node;
while (scanf("%s", c1)) {
if (strcmp(c1,"END") == 0) break;
scanf("%s", c2);
build(head, c2, c1);
}
scanf("%s%*c", c1);
while (gets(c)) {
if (strcmp(c, "END") == 0) break;
int len = strlen(c);
for (int i=0; i<len; ) {
int j = 0;
while (i<len && isalpha(c[i])) {
c1[j++] = c[i++];
}
if (j>0) {
c1[j] = '\0';
c2[0] = '\0';
find(head, c1, c2);
if (c2[0] != '\0') {
printf("%s", c2);
}else {
printf("%s", c1);
}
}else {
printf("%c", c[i]);
i++;
}
}
printf("\n");
}
}
return 0;
}
描述:求前缀中包含给定串的单词数。
变形:结点记录的信息是建树时经过该结点的次数。
描述:手机智能拼音输入法[见题]
反思:strcmp()函数搞错,wa数次,查错过错很纠结!
代码
#include <stdio.h>
#include <string.h>
struct Node {
Node * t[26];
int per;
Node() {
for (int i = 0; i < 26; i++) {
t[i] = NULL;
}
per = 0;
}
};
char ans[110], cc[110];
int pp;
Node *head;
char dg[10][5] = {
{},
{},
{3, 'a', 'b', 'c'},
{3, 'd', 'e', 'f'},
{3, 'g', 'h', 'i'},
{3, 'j', 'k', 'l'},
{3, 'm', 'n', 'o'},
{4, 'p', 'q', 'r', 's'},
{3, 't', 'u', 'v'},
{4, 'w', 'x', 'y', 'z'}
};
void build(Node *p, char *c, int per) {
p->per += per;
if (*c == '\0') return;
int k = *c - 'a';
if (p->t[k] == NULL) {
p->t[k] = new Node;
}
build(p->t[k], c + 1, per);
}
void find(Node *p, char *c, char *c1) {
if (*c == '\0') {
*c1 = '\0';
if (ans[0] == '\0') {
strcpy(ans, cc);
pp = p->per;
} else {
if (p->per > pp) {
strcpy(ans, cc);
pp = p->per;
} else if (p->per == pp) {
if (strcmp(ans, cc) > 0) { //key 写成 ‘<’ 了
strcpy(ans, cc);
}
}
}
return;
}
int k = *c - '0';
for (int i = 1; i <= dg[k][0]; i++) {
int j = dg[k][i] - 'a';
if (p->t[j] == NULL) continue;
*c1 = dg[k][i];
find(p->t[j], c + 1, c1 + 1);
}
}
int main() {
// freopen("datain", "r", stdin);
// freopen("dataout", "w", stdout);
int t, cs = 1;
int w, m, i, j, per;
char c[130], dig[110];
scanf("%d", &t);
while (t--) {
head = new Node;
scanf("%d", &w);
while (w--) {
scanf("%s%d", c, &per);
build(head, c, per);
}
printf("Scenario #%d:\n", cs++);
scanf("%d", &m);
while (m--) {
scanf("%s", dig);
int len = strlen(dig);
for (i = 1; i < len; i++) {
char c0[110], c1[110];
strncpy(c0, dig, i);
c0[i] = '\0';
ans[0] = '\0';
pp = 0;
// printf("%s ", c0);
find(head, c0, cc);
// ans[i] = '\0';
if (ans[0] == '\0') {
printf("MANUALLY\n");
} else {
printf("%s\n", ans);
}
}
printf("\n");
}
printf("\n");
}
return 0;
}
描述:同hdu-1075.
Say_Sth:这次用非递归写的,当然比递归的快点,可以当模板。
字典树模板
#include <stdio.h>
#include <string.h>
#define F 26 //字符集规模
#define M 13 //单词最大长度
struct Node {
Node *t[F];
char word[M]; //结点保存的信息
Node () { //initicalize
for (int i=0; i<F; i++) {
t[i] = NULL;
}
word[0] = 0;
}
};
Node *head;
void build(Node *p, char *c1, char *c2) {
Node *p1 = p;
while (*c1) {
int k = *c1-'a';
if (p1->t[k] == 0) p1->t[k] = new Node;
p1 = p1->t[k];
c1++;
}
strcpy(p1->word, c2);
}
bool find(Node *p, char *c1, char *c2) {
Node *p1 = p;
while (*c1) {
int k = *c1-'a';
if (p1->t[k]) p1 = p1->t[k];
else return false;
c1++;
}
strcpy(c2, p1->word);
return true;
}
int main()
{
// freopen("datain", "r", stdin);
char c[M*3], c1[M], c2[M];
head = new Node;
while (gets(c)) {
if (!strcmp(c,"")) break;
sscanf(c, "%s%s", c1, c2);
build(head, c2, c1);
}
while (scanf("%s", c1) != EOF) {
if (find(head, c1, c2)) {
printf("%s\n", c2);
}else {
printf("eh\n");
}
}
return 0;
}