字典樹:字符串的包含

題面:

給定一些僅有 01 組成的二進制編碼串, 詢問是否存在一個串是另一個串的前綴

多組數據輸入。每組數據中包含多個僅有01組成的字符串,以一個9作爲該組數據結束的標誌。

對於第 k 組數據(從1開始標號),如果不存在一個字符串使另一個的前綴,輸出"Set k is immediately decodable",否則輸出"Set k is not immediately decodable"。

每組數據的輸出單獨一行

sample input:
01
10
0010
0000
9
01
10
010
0000
9

sample output:
Set 1 is immediately decodable
Set 2 is not immediately decodable

字典樹:

  • 用於單個字符串與一堆字符串之間的匹配
  • 從根節點開始插入所有字符串,每一次遇到沒有分配過的節點就創建新的節點並標記所有字符串末尾的節點,構建字典樹
  • 插入函數示例:
    在這裏插入圖片描述
  • query函數用於查詢是否存在某一個字符串是str的完整前綴,查詢過程中flag==1,說明遇到了字符串的結尾,說明存在字符串是給定的字符串的完整前綴

思路:

  • 本題題意爲一個字符串與一個字符串集合匹配,所以考慮使用字典樹
  • 由於本題中只存在01兩種字符,所以charset設置爲2即可
  • 首先往字典樹中一次插入每個字符串,假設當前字符串爲S,需要判斷兩種情況:S是否是之前某個字符串的前綴,之前是否有某個字符串是S的前綴
  • 當S插入結束後,其最後一個節點是字典樹中已經存在的節點,說明S爲之前某個字符串的前綴
  • 在S的插入過程中,如果遇到某個字符串的結尾(判斷flag),說明存在某個字符串是S的前綴
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<string>
using namespace std;
const int N=100001,charset=2;//字典樹最多的節點個數,charset字符種類數 
struct tire
{
 int tot,root;//節點編號,root爲根節點編號 
 int child[N][charset],flag[N];//flag[now]=1表示now是某一個字符串的結尾 
 tire()
 {
  memset(child,-1,sizeof(child));
  memset(flag,0,sizeof(flag));
  root=0;
  tot=0;
 }
 void clear()
 {
  memset(child,-1,sizeof(child));
  memset(flag,0,sizeof(flag));
  root=0;
  tot=0;
  } 
 int insert(char *str)
 {
  int now=root;
  int jud=0,len=strlen(str);
  for(int i=0;i<len;i++)
  {
   int temp=str[i]-'0';
   if(child[now][temp]==-1)//節點now沒有第temp個兒子
   {
    child[now][temp]=++tot;
    flag[now]=0;
    } 
   else if(i==len-1||flag[child[now][temp]])//flag[child[now==1說明之前某個字符串是S的前綴 
    jud=1;
   now=child[now][temp];//i==len-1並且child[now !=-1說明給定的是之前某個字符串的前綴
   } 
  flag[now]=1;//標記該節點爲字符的結尾
  return jud; 
 }
 bool query(char *str)
 {
  //查詢字典樹中是否存在某個完整的字符串是str的前綴
  int now=root;
  for(int i=0;i<strlen(str);i++)
  {
   int x=str[i]-'0';
   if(child[now][x]==-1)
    return false;//還沒有找到尾就到頭了
   if(flag[now]) return true;//已經找到了一個字符子串
   now=child[now][x]; 
   } 
  return false;//到頭了還是沒有找到一個子串 
 }
};
int main()
{
 tire t;
 string s;
 char c[1001];
 int count=0;
 bool fl=false;
 while(cin>>s)
 {
  if(s=="9")
  {
   count++;
   if(!fl)
    cout<<"Set "<<count<<" is immediately decodable"<<endl;
   else 
    cout<<"Set "<<count<<" is not immediately decodable"<<endl;
   t.clear();
   fl=false;
   continue;
  }
  strcpy(c,s.c_str());
  if(t.insert(c))
   fl=true;
 }
 return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章