Trie树(字典树、前缀树)面向对象思想C++实现

Trie树的功能、思想、实现都写在代码注释中了

使用:
Trie trie = new Trie([TypeCase]);
trie.
TypeCase=
Bit //二进制
Number // 0-9数字
LowerCase //小写字母

这样就可以使用Trie树类了

代码:

//—————————————————————–

#pragma once

/**

功能:

1、字符串检索

检索/查询功能是Trie树最原始的功能。

2、搜索引擎系统

用于文本词频统计

3、字符串排序

4、前缀匹配

5、作为其他数据结构和算法的辅助结构(如AC自动机)

*/

/**

Trie树特性:

1)根节点不包含字符,除根节点外每一个节点都只包含一个字符。

2)从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。

3)每个节点的所有子节点包含的字符都不相同。

4)如果字符的种数为n,则每个结点的出度为n,这也是空间换时间的体现,浪费了很多的空间。

5)插入查找的复杂度为O(n),n为字符串长度。

*/



enum TypeCase

{

Bit = 2,//二进制

Number = 10,//0-9

LowerCase = 26//小写字母

};

class Trie

{

public:

explicit Trie(TypeCase _next) :count(0), typeCase(_next),fail(nullptr) {

next = new Trie*[typeCase];

for (auto beg(0); beg < typeCase; ++beg) next[beg] = nullptr;};

Trie() = delete;

~Trie(){delete []next;};

/**

1、插入:

假设存在字符串str,Trie树的根结点为root。i=0,p=root。

1)取str[i],判断p->next[str[i]-97]是否为空,若为空,则建立结点temp,并将p->next[str[i]-97]指向temp,然后p指向temp;若不为空,则p=p->next[str[i]-97];

2)i++,继续取str[i],循环1)中的操作,直到遇到结束符'\0',此时将当前结点p中的 exist置为true。

*/

bool InsertTrie(const std::string &str);

/**

2、查找

假设要查找的字符串为str,Trie树的根结点为root,i=0,p=root

1)取str[i],判断判断p->next[str[i]-97]是否为空,若为空,则返回false;若不为空,则p=p->next[str[i]-97],继续取字符。

2)重复1)中的操作直到遇到结束符'\0',若当前结点p不为空并且 exist 为true,则返回true,否则返回false。*/

bool SearchTrie(const std::string &str);

private:

size_t count;// 统计单词前缀出现的次数 

TypeCase typeCase;//Trie tree's type

Trie* fail;//AC自动机Fail指针

Trie **next;    // 指向各个子树的指针  

};

inline bool Trie::InsertTrie(const std::string &str)

{

auto strIterator(str.begin());

auto strEnd(str.end());

auto trieCount(0);

// ReSharper disable once CppInitializedValueIsAlwaysRewritten

size_t strIteratorToInt(0);

auto trieThis(this);

while (strIterator != strEnd)

{

switch(typeCase)

{

case 2:  strIteratorToInt = static_cast(*strIterator) - 48;

if (strIteratorToInt < 0 || strIteratorToInt>1) return false;

break;

case 10:

strIteratorToInt = static_cast(*strIterator) - 48;

if (strIteratorToInt < 0 || strIteratorToInt>9) return false;

break;

case 26:strIteratorToInt = static_cast(*strIterator) - 97;

if (strIteratorToInt < 0 || strIteratorToInt>26) return false;

break;

default:return false;

}

if (!trieThis->next[strIteratorToInt]) {

// ReSharper disable once CppNonReclaimedResourceAcquisition

auto temp = new Trie(typeCase);

temp->count = trieThis->count + 1;

trieThis->next[strIteratorToInt] = temp;

trieThis = temp;

}

else trieThis = trieThis->next[strIteratorToInt];

++strIterator;

}

return true;

}



inline bool Trie::SearchTrie(const std::string &str)

{

auto strIterator(str.begin());

auto strEnd(str.end());

// ReSharper disable once CppInitializedValueIsAlwaysRewritten

auto strIteratorToInt(0);

auto trieThis(this);

while (strIterator != strEnd)

{

switch (typeCase)

{

case 2:  strIteratorToInt = static_cast(*strIterator) - 48;//限制非法输入

if (strIteratorToInt < 0 || strIteratorToInt>1) return false;

break;

case 10:

strIteratorToInt = static_cast(*strIterator) - 48;//限制非法输入

if (strIteratorToInt < 0 || strIteratorToInt>9) return false;

break;

case 26:strIteratorToInt = static_cast(*strIterator) - 97;//限制非法输入

if (strIteratorToInt < 0 || strIteratorToInt>26) return false;

break;

default:return false;

}

if (trieThis->next[strIteratorToInt]) {

trieThis = trieThis->next[strIteratorToInt];

}

else return false;

++strIterator;

}

return true;

}

你可能感兴趣的:(算法,<数据结构>)