<address id="ousso"></address>
<form id="ousso"><track id="ousso"><big id="ousso"></big></track></form>
  1. C語言

    C#TrieTree介紹及實現方法

    時間:2025-04-01 17:49:45 C語言 我要投稿
    • 相關推薦

    C#TrieTree介紹及實現方法

      TrieTree簡單的說是一種多叉樹,每個節點保存一個字符,這么做的好處是當我們要做NGram比對時,只需要直接從樹的根節點開始沿著某個樹叉遍歷下去,就能完成比對。下面小編為大家整理了C#TrieTree介紹及實現方法,希望能幫到大家!

      在自然語言處理(NLP)研究中,NGram是最基本但也是最有用的一種比對方式,這里的N是需要比對的字符串的長度,而今天我介紹的TrieTree,正是和NGram密切相關的一種數據結構,有人稱之為字典樹。TrieTree簡單的說是一種多叉樹,每個節點保存一個字符,這么做的好處是當我們要做NGram比對時,只需要直接從樹的根節點開始沿著某個樹叉遍歷下去,就能完成比對;如果沒找到,停止本次遍歷。這話講得有些抽象,我們來看一個實際的例子。

      假設我們現在詞庫里面有以下一些詞:

      上海市

      上海灘

      上海人

      上海公司

      北京

      北斗星

      楊柳

      楊浦區

      如圖所示:掛在根節點上的字有上、北、楊,

      如果我們現在對“上海市楊浦區”這個詞做3gram就有上海市、海市楊、市楊浦、楊浦區,現在我們要知道哪些詞是能夠被這個字典識別的,通常我們可以用NGram來做分詞。有了這顆樹,我們只需要依次取每個字符,從根開始進行比對,比如上海市,我們能夠匹配 上->海->市,這個路徑,所以匹配;比如海市楊,由于沒有“海”字掛在根節點上,所以停止;市楊浦也無法匹配;最終匹配楊浦區,得到 楊->浦->區 這個路徑,匹配。

      最終我們可以把“上海市楊浦區”切分為 上海市|楊浦區。

      盡管TrieTree要比普通字符串數組節省很多時間,但這并不是沒有代價的,因為你要先根據字典構建這棵樹,這個代價并不低,當然對于某個應用來說一旦TrieTree構建完成就可以重復使用,所以針對大規模比對來說,性能提升還是很客觀的。

      下面是TrieTree的C#實現。

      復制代碼 代碼如下:

      public class TrieTree

      {

      TrieNode _root = null;

      private TrieTree()

      {

      _root = new TrieNode(char.MaxValue,0);

      charCount = 0;

      }

      static TrieTree _instance = null;

      public static TrieTree GetInstance()

      {

      if (_instance == null)

      {

      _instance = new TrieTree();

      }

      return _instance;

      }

      public TrieNode Root

      {

      get { return _root;

      }

      }

      public void AddWord(char ch)

      {

      TrieNode newnode=_root.AddChild(ch);

      newnode.IncreaseFrequency();

      newnode.WordEnded = true;

      } int charCount;

      public void AddWord(string word)

      {

      if (word.Length == 1)

      {

      AddWord(word[0]);

      charCount++;

      }

      else

      {

      char[] chars=word.ToCharArray();

      TrieNode node = _root;

      charCount += chars.Length;

      for (int i = 0; i < chars.Length; i++)

      {

      TrieNode newnode=node.AddChild(chars[i]);

      newnode.IncreaseFrequency();

      node = newnode;

      }

      node.WordEnded = true;

      }

      }

      public int GetFrequency(char ch)

      {

      TrieNode matchedNode = _root.Children.FirstOrDefault(n => n.Character == ch);

      if (matchedNode == null)

      {

      return 0;

      }

      return matchedNode.Frequency;

      }

      public int GetFrequency(string word)

      {

      if (word.Length == 1)

      {

      return GetFrequency(word[0]);

      }

      else

      {

      char[] chars = word.ToCharArray();

      TrieNode node = _root;

      for (int i = 0; i < chars.Length; i++)

      {

      if (node.Children == null)

      return 0;

      TrieNode matchednode = node.Children.FirstOrDefault(n => n.Character == chars[i]);

      if (matchednode == null)

      {

      return 0;

      }

      node = matchednode;

      }

      if (node.WordEnded == true)

      return node.Frequency;

      else

      return -1;

      }

      }

      }

      這里我們使用了單例模式,因為TrieTree類似緩存,不需要重復創建。下面是TreeNode的實現:

      復制代碼 代碼如下:

      public class TrieNode

      {

      public TrieNode(char ch,int depth)

      {

      this.Character=ch;

      this._depth=depth;

      }

      public char Character;

      int _depth;

      public int Depth

      {

      get{return _depth;

      }

      }

      TrieNode _parent=null;

      public TrieNode Parent

      {

      get {

      return _parent;

      }

      set { _parent = value;

      }

      }

      public bool WordEnded = false;

      HashSet_children=null;

      public HashSetChildren

      {

      get {

      return _children;

      }

      }

      public TrieNode GetChildNode(char ch)

      {

      if (_children != null)

      return _children.FirstOrDefault(n => n.Character == ch);

      else

      return null;

      }

      public TrieNode AddChild(char ch)

      {

      TrieNode matchedNode=null;

      if (_children != null)

      {

      matchedNode = _children.FirstOrDefault(n => n.Character == ch);

      }

      if (matchedNode != null)

      //found the char in the list

      {

      //matchedNode.IncreaseFrequency();

      return matchedNode;

      }

      else

      {

      //not found

      TrieNode node = new TrieNode(ch, this.Depth + 1);

      node.Parent = this;

      //node.IncreaseFrequency();

      if (_children == null)

      _children = new HashSet();

      _children.Add(node);

      return node;

      }

      }

      int _frequency = 0;

      public int Frequency

      {

      get { return _frequency;

      }

      }

      public void IncreaseFrequency()

      {

      _frequency++;

      }

      public string GetWord()

      {

      TrieNode tmp=this;

      string result = string.Empty;

      while(tmp.Parent!=null) //until root node

      {

      result = tmp.Character + result;

      tmp = tmp.Parent;

      }

      return result;

      }

      public override string ToString()

      {

      return Convert.ToString(this.Character);

      }

      }

    【C#TrieTree介紹及實現方法】相關文章:

    java算法實現排列組合的方法介紹09-23

    實現員工激勵的方法08-28

    JAVA實現生成GUID的方法06-02

    Java實現多線程的方法11-10

    php頁面緩存實現方法07-20

    關于Java動態實現的方法08-23

    PHP實現多線程的方法08-02

    PHP列表頁實現的方法05-24

    PHP多線程的實現方法09-06

    <address id="ousso"></address>
    <form id="ousso"><track id="ousso"><big id="ousso"></big></track></form>
    1. 日日做夜狠狠爱欧美黑人