天天看點

ACM_模闆_字典樹

字典樹Trie是一門比較簡單也比較好懂的算法,因為字典本身是生活中使用率較高的工具,字典的工作原理大家也都懂,其本質也就是字首查詢,對字首查詢的方法,大家很容易可以想到資料結構中的連結清單結構,用指針去實作一個連接配接作用。在這裡,小編先講解一下數的指針建立。

首先因為我們字母隻有26個,每個節點的指向可以加一個26節點的指針(不考慮大小寫),在每輸入一個字元串的時候就建立節點。

小編先給出指針實作的字典樹模闆:

#include <iostream>//指針實作
#include <cstdio>
#include <cstring>
using namespace std;
char str[11];
struct node
{
  node *next[26];
  int cnt;
  node()
  {//構造函數,建立結點時自動執行
    cnt=0;
    for(int i=0; i<26; i++)
      next[i] = NULL;//将該節點的下面的26個節點初始化為空
  }
};
void insert(node *p,char *str)
{
  for(int i=0; str[i]; i++)
  {
    int t=str[i]-'a';
    if(p->next[t] == NULL)
      p->next[t] = new node;//如果節點不存在,那麼先new一個
    p = p->next[t];
    p->cnt++;
  }
}
int find(node *p,char *str)
{
  for(int i=0; str[i]; i++)
  {
    int t=str[i]-'a';
    p = p->next[t];
    if(!p) return 0;
  }
  return p->cnt;
}
int main()
{
  node *root=new node();
  while(gets(str)&&strlen(str))
    insert(root,str);
  while(gets(str))
  {
    int ans=find(root,str);
    printf("%d\n",ans);
  }
  return 0;
}      

指針由于使用時,速度會很慢,是以我們在使用的時候有時會很可能逾時(TLE),是以我們可以雲耀到數組去模拟指針位址。

小編這裡額給出小編的數組模拟字典樹Trie模闆。

#include <cstdio>//數組模拟實作 
#include <cstring>
#define N 5000000
int tree[N][26],cnt[N];
char str[20];
int tot;
void insertTrie(char *str)
{
  int len=strlen(str);
  int now=0;
  for(int i=0; i<len; i++)
  {
    int w=str[i]-'a';
    if(tree[now][w] == 0) tree[now][w] = ++tot;
    now = tree[now][w];
    cnt[now]++;
  }
}
int searchTrie(char *str)
{
  int len=strlen(str);
  int now=0;
  for(int i=0; i<len; i++)
  {
    int w=str[i]-'a';
    if(tree[now][w] == 0) return 0;
    now = tree[now][w];
  }
  return cnt[now];
}
int main()
{
  while(gets(str)&&strcmp(str,"")!=0)
    insertTrie(str);
  while(gets(str))
    printf("%d\n",searchTrie(str));
  return 0;
}