字典树

来源:互联网 发布:引出数据失败 请检查 编辑:程序博客网 时间:2024/06/05 14:07

1、什么是字典树

就是用来存放一定长度的字符串(长度不于过大),可以很快的查找一组字符串中某个字符串出现的次数

字典树是一种以空间换时间的算法,如果这个字典树存储的是a~z,那么一个字符下面对应26个字符,即长度为1的字符最多需要26个存储空间,长度为2的字符最多需要26*26个存储空间,长度为3的字符串最多需要26*26*26个存储空间。。。


c++实现:

#include <iostream>
#include <cstdio>
#include <cstring>

#define MAX 26

using namespace std;

/**
 * 字典树是一种以空间换时间的算法,如果这个字典树存储的是a~z,那么一个字符下面对应26个字符,即长度为1的字符最多需要26个存储空间,长度为2的字符最多需要26*26个存储空间
 * 长度为3的字符串最多需要26*26*26个存储空间,。。。
 */

typedef struct TreeNode {
    TreeNode *next[MAX], *p;
    int num;
    // str为当前所存储的字符串
    char str[11];
}TreeNode;

class DictTree {
private:
    TreeNode *t, *max;

    TreeNode *create() {
        static int i;
        static TreeNode *nt;
        nt = new TreeNode();
        nt->num = 0;
        for(i = 0;i < MAX;++i) {
            nt->next[i] = NULL;
        }
        return nt;
    }
    void deleteC(TreeNode *nt) {
        static int i;
        for(i = 0;i < MAX;++i)
            if(nt->next[i] != NULL) {
                deleteC(nt->next[i]);
                delete[] nt->next[i];
                nt->next[i] = NULL;
            }
    }
public:
    TreeNode *T;
    DictTree() {
        T = t = this->create();
        t->p = NULL;
        max = t;
    }
    ~DictTree() {
        // 将字典树进行销毁
        deleteC(T);
    }
    void insert(const char *str) {
        static int len, i;

        len = strlen(str);
        this->t    = this->T;
        t = T;
        for(i = 0;i < len;++i) {
            if(t->next[str[i]-'a'] == NULL) {
                t->next[str[i]-'a'] = create();
                t->next[str[i]-'a']->p = t;
                t = t->next[str[i]-'a'];

                strcpy(t->str, t->p->str);
                this->t->str[i] = str[i];
                t->str[i+1] = '\0';
            } else {
                t = t->next[str[i]-'a'];
            }
        }
        ++t->num;
        if(this->t->num > this->max->num)
            this->max = this->t;
    }
    // 将出现字符串最多的返回
    TreeNode numMaxString() {
        return *this->max;
    }
    // 查询当前字符串出现的个数
    long search(const char *str) {
        this->t = this->T;
        static int i, len;
        len = strlen(str);
        
        for(i = 0;i < len;++i) {
            if(t->next[str[i]-'a'] == NULL) {
                return 0;
            }
            t = t->next[str[i]-'a'];
        }
        return t->num;
    }
};

int main() {
    DictTree dt;
    int T;
    char str[11];
    scanf("%d", &T);
    while(T--) {
        scanf("%s", str);
        dt.insert(str);
    }
    TreeNode t = dt.numMaxString();
    
    printf("%s %d\n", t.str, t.num);
/*    while(1) {
        scanf("%s", str);
        printf("%s %ld\n", str, dt.search(str));
    }*/
    return 0;
}

可以ac 南阳acm题目290

http://acm.nyist.net/JudgeOnline/problem.php?pid=290

原创粉丝点击