杭电1251——统计难题(字典树的应用)

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1251

主要算法:
该题运用了字典树的知识。输入单词时,建立字典树。每个节点的v的值代表从根节点到该节点路径上所有字母组成的前缀出现的次数。当输入前缀时,只需查找字典树中是否有该前缀,若有,输出前缀的最后一个字母的v 的值,若无,输出0.

AC代码:

# include
# include
# include
# define MAX 26

typedef struct Trie{
    struct Trie *next[MAX];
    int v;//记录以该节点为最后一个字母的前缀出现的次数
}Trie;

Trie * root=NULL;

void insertTrie(char words[]);
void createTrie();
int search(char perfix[]);

int main()
{
    createTrie();
    char perfix[10];
    while(scanf("%s",perfix)!=EOF)
    {
        printf("%d\n",search(perfix));
    }
    return 0;
}

//建立字典树
void createTrie()
{
    int i;
    char words[12];
    if(!root)
        root=(Trie *)malloc(sizeof(Trie));
    for(i=0;inext[i]=NULL;
    root->v=0;
    while(gets(words)&&strcmp(words,"\0")!=0)//gets()函数读入整行数据,并且将'\n'换成'\0'
    {
        insertTrie(words);
    }

}

//将单词插入字典树中
void insertTrie(char words[])
{
    Trie *p=root;
    int len=strlen(words),i,j;
    for(i=0;iint id=words[i]-'a';
        if(p->next[id]==NULL)//该层上不存在‘a’+id的节点,新建,并且置v=1
        {
            p->next[id]=(Trie *)malloc(sizeof(Trie));
            p=p->next[id];
            p->v=1;
            for(j=0;jnext[j]=NULL;
        }
        else
        {
            p=p->next[id];
            (p->v)++;
        }
    }
}

//在字典树中查询是否存在前缀
int search(char perfix[])
{
    Trie *p=root;
    int len=strlen(perfix),i;
    for(i=0;iint id=perfix[i]-'a';
        if(p->next[id]==NULL)
            break;
        p=p->next[id];
    }
    if(ireturn 0;
    else
        return p->v;
}

你可能感兴趣的:(杭电acm)