最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

字典樹(shù)的基本知識(shí)及使用C語(yǔ)言的相關(guān)實(shí)現(xiàn)

 更新時(shí)間:2015年08月07日 11:39:42   作者:zinss26914  
這篇文章主要介紹了字典樹(shù)的基本知識(shí)及使用C語(yǔ)言的相關(guān)實(shí)現(xiàn),這也是ACM等計(jì)算機(jī)考試和競(jìng)賽題目的基本知識(shí),需要的朋友可以參考下

概念

     如果我們有and,as,at,cn,com這些關(guān)鍵詞,那么trie樹(shù)(字典樹(shù))是這樣的:

201587113000993.png (702×500)

     從上面的圖中,我們或多或少的可以發(fā)現(xiàn)一些好玩的特性。

      第一:根節(jié)點(diǎn)不包含字符,除根節(jié)點(diǎn)外的每一個(gè)子節(jié)點(diǎn)都包含一個(gè)字符。

      第二:從根節(jié)點(diǎn)到某一節(jié)點(diǎn),路徑上經(jīng)過(guò)的字符連接起來(lái),就是該節(jié)點(diǎn)對(duì)應(yīng)的字符串。

      第三:每個(gè)單詞的公共前綴作為一個(gè)字符節(jié)點(diǎn)保存。

 

使用范圍

     既然學(xué)Trie樹(shù),我們肯定要知道這玩意是用來(lái)干嘛的。

     第一:詞頻統(tǒng)計(jì)。

            可能有人要說(shuō)了,詞頻統(tǒng)計(jì)簡(jiǎn)單啊,一個(gè)hash或者一個(gè)堆就可以打完收工,但問(wèn)題來(lái)了,如果內(nèi)存有限呢?還能這么

             玩嗎?所以這里我們就可以用trie樹(shù)來(lái)壓縮下空間,因?yàn)楣睬熬Y都是用一個(gè)節(jié)點(diǎn)保存的。

     第二: 前綴匹配

            就拿上面的圖來(lái)說(shuō)吧,如果我想獲取所有以"a"開(kāi)頭的字符串,從圖中可以很明顯的看到是:and,as,at,如果不用trie樹(shù),

            你該怎么做呢?很顯然樸素的做法時(shí)間復(fù)雜度為O(N2) ,那么用Trie樹(shù)就不一樣了,它可以做到h,h為你檢索單詞的長(zhǎng)度,

            可以說(shuō)這是秒殺的效果。

數(shù)據(jù)結(jié)構(gòu)定義

  #define MAX 26 // 字符集大小 
   
  typedef struct trieNode { 
    struct trieNode *next[MAX]; 
    int count; // 記錄該字符出現(xiàn)次數(shù) 
  } trieNode; 



next數(shù)組表示每層有多少類(lèi)的數(shù),如果只是小寫(xiě)字母,26即可


實(shí)現(xiàn)方法
搜索字典項(xiàng)目的方法:

  •     從根節(jié)點(diǎn)開(kāi)始一次搜索
  •     獲取要查找關(guān)鍵詞的第一個(gè)字母,并根據(jù)該字母選擇對(duì)應(yīng)的子樹(shù)并轉(zhuǎn)到該子樹(shù)繼續(xù)進(jìn)行檢索
  •     在相應(yīng)的子樹(shù)上,獲取要查找關(guān)鍵詞的第二個(gè)字母,并進(jìn)一步選擇對(duì)應(yīng)的子樹(shù)進(jìn)行檢索
  •     迭代過(guò)程
  •     在某個(gè)節(jié)點(diǎn)處,關(guān)鍵詞的所有字母已被取出,則讀取附在該結(jié)點(diǎn)上的信息,即完成查找


其他操作類(lèi)似


實(shí)現(xiàn)模板

初始化根結(jié)點(diǎn)

  /** 
   * 初始化Trie樹(shù)根結(jié)點(diǎn) 
   */ 
  void initTrie(trieNode **root) 
  { 
    int i; 
   
    *root = (trieNode *)malloc(sizeof(trieNode)); 
    (*root)->count = 0; 
   
    for (i = 0; i < MAX; i ++) { 
      (*root)->next[i] = NULL; 
    } 
  } 

插入單詞到trie樹(shù)

 

  /** 
   * Trie樹(shù)插入操作 
   */ 
  void insert(char *str, trieNode *root) 
  { 
    int i; 
   
    trieNode *p = root; 
   
    while (*str != '\0') { 
      if (p->next[*str - 'a'] == NULL) { 
        trieNode *tmp = (trieNode *)malloc(sizeof(trieNode)); 
        for (i = 0; i < MAX; i ++) { 
          tmp->next[i] = NULL; 
        } 
        tmp->count = 1; 
        p->next[*str - 'a'] = tmp; 
        p = p->next[*str - 'a']; 
      } else { 
        p = p->next[*str - 'a']; 
        p->count ++; 
      } 
   
      str ++; 
    } 
  } 

統(tǒng)計(jì)查找單詞數(shù)量

  /** 
   * 統(tǒng)計(jì)前綴出現(xiàn)次數(shù) 
   */ 
  int count(char *search, trieNode *root) 
  { 
    trieNode *p = root; 
   
    while (*search != '\0') { 
      if (p->next[*search - 'a'] == NULL) { 
        return 0; 
      } else { 
        p = p->next[*search - 'a']; 
        search ++; 
      } 
    } 
   
    return p->count; 
  } 


清理trie樹(shù)

  /** 
   * 清理trie樹(shù) 
   */ 
  void delTrie(trieNode *root) 
  { 
    int i; 
   
    for (i = 0; i < MAX; i ++) { 
      if (root->next[i] != NULL) { 
        delTrie(root->next[i]); 
      } 
    } 
   
    free(root); 
  } 

時(shí)間復(fù)雜度
插入、查找的時(shí)間復(fù)雜度均為O(n),n為字符串的長(zhǎng)度

空間復(fù)雜度較高,O(26^n),典型空間換時(shí)間


參考題目

ac代碼:

 

  #include <stdio.h> 
  #include <stdlib.h> 
  #include <string.h> 
   
  #define MAX 26 // 字符集大小 
   
  typedef struct trieNode { 
    struct trieNode *next[MAX]; 
    int count; // 記錄該字符出現(xiàn)次數(shù) 
  } trieNode; 
   
   
  /** 
   * 初始化Trie樹(shù)根結(jié)點(diǎn) 
   */ 
  void initTrie(trieNode **root) 
  { 
    int i; 
   
    *root = (trieNode *)malloc(sizeof(trieNode)); 
    (*root)->count = 0; 
   
    for (i = 0; i < MAX; i ++) { 
      (*root)->next[i] = NULL; 
    } 
  } 
   
  /** 
   * Trie樹(shù)插入操作 
   */ 
  void insert(char *str, trieNode *root) 
  { 
    int i; 
   
    trieNode *p = root; 
   
    while (*str != '\0') { 
      if (p->next[*str - 'a'] == NULL) { 
        trieNode *tmp = (trieNode *)malloc(sizeof(trieNode)); 
        for (i = 0; i < MAX; i ++) { 
          tmp->next[i] = NULL; 
        } 
        tmp->count = 1; 
        p->next[*str - 'a'] = tmp; 
        p = p->next[*str - 'a']; 
      } else { 
        p = p->next[*str - 'a']; 
        p->count ++; 
      } 
   
      str ++; 
    } 
  } 
   
  /** 
   * 統(tǒng)計(jì)前綴出現(xiàn)次數(shù) 
   */ 
  int count(char *search, trieNode *root) 
  { 
    trieNode *p = root; 
   
    while (*search != '\0') { 
      if (p->next[*search - 'a'] == NULL) { 
        return 0; 
      } else { 
        p = p->next[*search - 'a']; 
        search ++; 
      } 
    } 
   
    return p->count; 
  } 
   
  /** 
   * 清理trie樹(shù) 
   */ 
  void delTrie(trieNode *root) 
  { 
    int i; 
   
    for (i = 0; i < MAX; i ++) { 
      if (root->next[i] != NULL) { 
        delTrie(root->next[i]); 
      } 
    } 
   
    free(root); 
  } 
   
   
  int main(void) 
  { 
    char str[15]; 
    trieNode *root; 
   
    // 初始化根結(jié)點(diǎn) 
    initTrie(&root); 
   
    while (gets(str) && str[0] != '\0') { 
      // 插入Trie樹(shù) 
      insert(str, root); 
    } 
   
    // 查找前綴出現(xiàn)次數(shù) 
    while (gets(str) && str[0] != '\0') { 
      printf("%d\n", count(str, root)); 
    } 
   
    delTrie(root); 
   
    return 0; 
  } 

相關(guān)文章

  • C語(yǔ)言求2的n次方多種方法總結(jié)

    C語(yǔ)言求2的n次方多種方法總結(jié)

    這篇文章主要給大家介紹了關(guān)于C語(yǔ)言求2的n次方多種方法的相關(guān)資料,求2的N次冪是一個(gè)常用的功能,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-10-10
  • C語(yǔ)言模擬實(shí)現(xiàn)C++的繼承與多態(tài)示例

    C語(yǔ)言模擬實(shí)現(xiàn)C++的繼承與多態(tài)示例

    本篇文章主要介紹了C語(yǔ)言模擬實(shí)現(xiàn)C++的繼承與多態(tài)示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • C/C++讀寫(xiě)JSON數(shù)據(jù)的詳細(xì)過(guò)程記錄

    C/C++讀寫(xiě)JSON數(shù)據(jù)的詳細(xì)過(guò)程記錄

    JSON文件無(wú)論是在web開(kāi)發(fā)、客戶(hù)端開(kāi)發(fā)、服務(wù)端等開(kāi)發(fā)中都是應(yīng)用比較廣泛的的第一種輕量級(jí)數(shù)據(jù)交換格式,非常方便閱讀和編寫(xiě),下面這篇文章主要給大家介紹了關(guān)于C/C++讀寫(xiě)JSON數(shù)據(jù)的詳細(xì)過(guò)程,需要的朋友可以參考下
    2023-04-04
  • C的|、||、&、&&、異或、~、!運(yùn)算符

    C的|、||、&、&&、異或、~、!運(yùn)算符

    這篇文章主要介紹了C的|、||、&、&&、異或、~、!運(yùn)算符,需要的朋友可以參考下
    2014-06-06
  • C++設(shè)計(jì)模式之裝飾模式(Decorator)

    C++設(shè)計(jì)模式之裝飾模式(Decorator)

    這篇文章主要為大家詳細(xì)介紹了C++設(shè)計(jì)模式之裝飾模式Decorator的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • C++整數(shù)拼接技巧大揭秘

    C++整數(shù)拼接技巧大揭秘

    C++整數(shù)拼接技巧大揭秘,讓你的代碼更簡(jiǎn)潔高效!你是否還在為如何優(yōu)雅地將整數(shù)拼接成字符串而煩惱?本指南將為你揭示C++中最實(shí)用、最酷炫的整數(shù)拼接技巧,助你提升編程技能,需要的朋友可以參考下
    2024-03-03
  • C++類(lèi)和對(duì)象之封裝詳解

    C++類(lèi)和對(duì)象之封裝詳解

    大家好,本篇文章主要講的是C++類(lèi)和對(duì)象之封裝詳解,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • c++實(shí)現(xiàn)新年煙花效果完整代碼

    c++實(shí)現(xiàn)新年煙花效果完整代碼

    這篇文章主要給大家介紹了關(guān)于c++實(shí)現(xiàn)新年煙花效果的相關(guān)資料,文中給出了詳細(xì)完整代碼,適合初學(xué)C語(yǔ)言/C++的小伙伴學(xué)習(xí)研究,需要的朋友可以參考下
    2023-11-11
  • C++中實(shí)現(xiàn)fibonacci數(shù)列的幾種方法

    C++中實(shí)現(xiàn)fibonacci數(shù)列的幾種方法

    本文主要介紹了C++中實(shí)現(xiàn)fibonacci數(shù)列的幾種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • C++實(shí)現(xiàn)數(shù)據(jù)文件存儲(chǔ)與加載

    C++實(shí)現(xiàn)數(shù)據(jù)文件存儲(chǔ)與加載

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)數(shù)據(jù)文件存儲(chǔ)與加載,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-06-06

最新評(píng)論

石嘴山市| 刚察县| 收藏| 石首市| 库车县| 昌吉市| 嘉义市| 基隆市| 新蔡县| 滨海县| 甘肃省| 龙游县| 泸西县| 靖边县| 涡阳县| 吉隆县| 洛扎县| 铜川市| 巴林右旗| 广昌县| 潞城市| 房产| 博乐市| 双牌县| 上饶市| 永济市| 锦屏县| 永胜县| 长沙市| 洛宁县| 环江| 舒城县| 普洱| 江津市| 安国市| 紫金县| 四子王旗| 博湖县| 政和县| 武强县| 开平市|