字典树的基本功能是用来查询某个单词(前缀)在所有单词中出现次数的一种数据结构,它的插入和查询复杂度都为O(len),Len为单词(前缀)长度,但是它的空间复杂度却非常高,如果字符集是26个字母,那每个节点的度就有26个,典型的以空间换时间结构。
这题就是统计一组字符串中某前缀出现次数
这题就是统计一组字符串中某前缀出现次数
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 26
#define LENTH 1000000
struct _Node{
int nCount;
struct _Node* next[MAX];
};
typedef struct _Node TrieNode;
TrieNode tn[LENTH];
int all=0;
//初始化
void init(TrieNode ** pRoot)
{
*pRoot = NULL;
}
//创建新结点
TrieNode * createNode()
{
int i;
TrieNode * p;
if(all < LENTH)p = &tn[all++];
else return NULL;
p->nCount = 1;
for(i = 0 ; i < MAX ; ++i)
{
p->next[i] = NULL;
}
return p;
}
//插入
void insertNode(TrieNode **pRoot,char *s)
{
TrieNode * p;
if(!(p=*pRoot))
{
p=*pRoot=createNode();
}
int i,k;
i = 0;
while(s[i])
{
k = s[i]-'a';
if(p->next[k])
p->next[k]->nCount++;
else{
p->next[k]=createNode();
}
p = p->next[k];
++i;
}
}
//查找
int searchTrie(TrieNode ** pRoot, char *s)
{
int i,k;
TrieNode * p;
if(!(p = *pRoot))return 0;
i = 0;
while(s[i])
{
k = s[i++]-'a';
if(p->next[k])
{
p=p->next[k];
}else{
return 0;
}
}
return p->nCount;
}
int main()
{
printf("hello world\n");
TrieNode * root;
init(&root);
char s[11];
while(gets(s)&&s[0])
{
insertNode(&root,s);
}
printf("插入结束\n");
while(gets(s))
{
printf("%d\n",searchTrie(&root,s));
}
return 0;
}
判断一组字符串中是否有一个字符串是另一个字符串的前缀(字典树第二类应用)。
我们只要在结点中添加一个nEndFlag成员变量即可。若nEndFlag == 1,说明该结点字符是某一字符串的结尾(假设为A),若在插入B字符串的过程中经过这一结点,则说明A是B的前缀;还有一种情况,当要插入最后一个字符c时,却发现p->next[c-'0']为真,则说明该字符串是一个前缀字符串,eg:先插入abcde,再插入abc这种情况
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 26
#define MAXLEN 1000000
struct _Node{
int nEndFlag;
struct _Node* next[MAX];
};
typedef struct _Node TrieNode;
TrieNode tn[MAXLEN];
int all = 0;
int nflag = 0;
void initTrie(TrieNode ** root)
{
*root = NULL;
}
TrieNode * createNode()
{
TrieNode *p;
p = &tn[all++];
p->nEndFlag = 0;
int i ;
for(i = 0;i < MAX ; ++i)
{
p->next[i] = NULL;
}
return p;
}
int insertNode(TrieNode ** pRoot,char *s)
{
TrieNode * p ;
if(!(p = *pRoot))
{
p = *pRoot = createNode();
}
int i =0,k;
while(s[i])
{
k = s[i++] - 'a';
if(p->next[k])
{
if(p->next[k]->nEndFlag == 1 || s[i] == '\0')
{
return 1;
}
}
else
{
p->next[k] = createNode();
}
p = p->next[k];
}
p->nEndFlag = 1;
return 0;
}
int main()
{
printf("hello world\n");
TrieNode * root;
initTrie(&root);
char s[11];
int i, n;
int flag = 0;
scanf("%d",&n);
getchar();
printf("%d",n);
for(i = 0;i < n; ++i)
{
gets(s);
puts(s);
printf("%d\n",i);
if(flag == 0){
flag = insertNode(&root,s);
}
}
flag?printf("YES\n"):printf("NO\n");
return 0;
}