假若需要这样的实现,我有一个词典,词典内容如下:

pad

park

panda

pan

apply

apple

append

app

application

需要统计以p为前缀的单词个数,好的,最直观的办法,我遍历所有的字符串,记数,ok,作业完成了!

A: 完成的很好!那现在我想要pa开始的~

Me: 嗯~好的,遍历,记数,ok~

A:我要app前缀的个数~

Me: 嗯?~好吧。。

A:appl的,pan的,前缀个数~

Me: ….

 

是不是很无奈,这个时候字典树就派上用场了。当然首先要明确的是,我们的目标是以空间换时间。

字典树,从根节点开始,每个节点可能的child数是26(如果只有英文小写字母的话),当然是随着词汇添加而完善这棵树的。

/*
 * =====================================================================================
 *       Filename:  Trie.cpp
 *    Description:  字典数的定义和使用
 *
 *        Version:  1.0
 *        Created:  08/22/2012 07:01:05 PM
 *
 *         Author:  zhy (), [email protected]
 * =====================================================================================
 
*/

#include <stdio.h>
#include < string.h>

#define MAX 26 // 可以变化,比如只有数字则为10

// 字典数的基础结构
struct Trie
{
    Trie()
    {
         for (  int i=0; i<MAX; ++i)
            next[i] = NULL;
        count = 1;
    }
    Trie *next[MAX]; // 下一层的节点数目,初始时指针全是null,当添加词汇后会逐步添加
     int count; // 前缀数目
};

Trie* root =  new Trie; // 根节点

// 根据str完善以root为根节点的词典树
void createTrie( const  char *str)
{
    Trie* p = root;
     while (*str) {
         int index = *str - 'a';
         if (p->next[index]!=NULL) {
            p->next[index]->count++; // 如果已经存在,前缀数目+1
        }  else {
            p->next[index] =  new Trie; // 不存在则建立
        }
        p = p->next[index];
        str++;
    }
}
// 查找str为前缀的词汇数目
int findTrie( const  char* str)
{
     int len = strlen(str);
     if (len == 0)
         return 0;

    Trie* p = root;
     // 逐个字符遍历str
     while (*str) {
         int index = *str - 'a';
         if (p->next[index] != NULL) {
            p = p->next[index]; // 该字符存在,试试下一个字符
        }  else {
             return 0; // 如果不存在该字符,则不存在该前缀
        }
        str++;
    }

     return p->count;
}

void destroyTrie(Trie* node)
{
     if (node == NULL)
         return;

     for (  int i=0; i<MAX; ++i) {
         if (node->next[i] != NULL) {
            destroyTrie(node->next[i]);
        }
    }

    delete node;
}

int main()
{
     char s[100];
    printf("input the words for trie\n");
     while (gets(s) && strlen(s))
    {
        createTrie(s);
    }

    printf("search what u want?:\n");
     while (gets(s) && strlen(s))
    {
        printf("%s: %d\n", s, findTrie(s));
    }

    destroyTrie(root);
     return 0;
}

运行结果:

y@y-VirtualBox:/mnt/mydocuments/Training$ ./Trie
input the words for trie
pad
park
panda
pan
apply
apple
append
app
application

search what u want?:
p
p: 4
a
a: 5
pa
pa: 4
pan
pan: 2
par
par: 1
app
app: 5
appl
appl: 3
appe
appe: 1