C# TrieTree介紹及實現方法

來源:互聯網
上載者:User

在自然語言處理(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<TrieNode> _children=null;
public HashSet<TrieNode> Children
{
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<TrieNode>();
_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);
}
}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.