统计难题(字典树模板题)

题意:

    Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀),这个题意还是很好理解的,输入方面稍微有一点点坑,但是习惯就好 = = 判断读入的是不是一串空得字符串,可以用gets()函数去实现,可以通过读入的字符串是不是为空判断。

链接:

   HDU 1251传送门

   点此查看C++与G++在提交时的区别

   B站Up主讲解的字典树写法

思路: 

    很简单的一道字典树模板题,先是去上面的链接学习了一下字典树的指针写法(up主讲的很不错,推荐当作入门的学习)。理解之后就学着敲了。提交的时候一直 Memory Limit Exceeded 实在是解决不了,又不想去学字典树的数组写法(太懒了)。直到今天早上看博客的时候才知道这题的指针写法应该用C++来提交这样就不会 Memory Limit Exceeded 了。字典树的理解可从上面的视频来理解。

代码:

#include 
#include 
#include 
#include 
using namespace std;
///用指针写的代码需要用c++提交,用G++会出现超内存的错误,总的来时,用指针的方式写比较容易理解,但是用数组的写法可能比较优
int n;
struct Node{
    Node *nxt[26];
    int flag;
    Node(){
        for(int i=0;i<26;i++)
            nxt[i]=NULL;
        flag=0;
    }
};
Node *root;
void init()
{
    root=new Node();
}

void delete_tree(Node * root)
{
	//递归删除
	for(int i=0; i<26; i++)
		if(root->nxt[i] != NULL)
			delete_tree(root->nxt[i]);
	delete root;
}
void ins(char *s){
    int len=strlen(s);
    Node *now=root;
    for(int i=0;inxt[to]==NULL)
            now->nxt[to]=new Node();
        now=now->nxt[to];
        now->flag++;
    }
}
char op[11];
int fid(char *s)
{
    int len=strlen(s);
    Node *now=root;
    for(int i=0;inxt[to]==NULL)
            return 0;
        now=now->nxt[to];
    }
    return now->flag;
}

int main()
{
    init();
    while(gets(op)){
        if(op[0]==NULL)
            break;
        ins(op);
    }
    while(scanf("%s",op)!=EOF)
        printf("%d\n",fid(op));
    delete_tree(root);
    return 0;
}

小提示:

     字典树是一种用空间换取时间的算法,因为是树结构,所以它的查找速度与插入速度都很快。注意在多组输入的时候需要用delete_tree的操作,不然会消耗很多内存,百分之八九十的概率会爆内存。

你可能感兴趣的:(字典树)