此次代码使用了诸多新鲜玩意,比如自动类型推断,模板类等等,感觉真的超级好玩啊。

自己做了一个简易的测试,程序的健壮性什么的还是比较差的,此程序留待以后进行功能补全。

#pragma once
#include<cstddef>
#include<string>
using std::strlen;
using std::pair;
using std::make_pair; //字典树节点
template<int size>
class TrieNode
{
public:
TrieNode() :NodeSize(), TerminableSize()
{
for (size_t i = ; i < size; i++)
{
ChildNode[i] = NULL;
}
}
~TrieNode()
{
for (size_t i = ; i < size; i++)
{
delete ChildNode[i];
ChildNode[i] = NULL;
}
} public: //为了方便,此处将变量暴露,后续可以改进为通过接口操作
int NodeSize; //记录此节点子节点的个数
int TerminableSize; //存储以此节点结尾的字符串个数
TrieNode* ChildNode[size]; //记录指向子节点的指针
}; //字典树
template < int Size, typename Type> class Trie
{
public:
typedef TrieNode<Size> Node;
typedef TrieNode<Size>* pNode; public:
Trie() :root(new Node) {}
~Trie() { delete root; } public:
template<typename itr>
void insert(itr beg, itr end);
void insert(const char* str); template<typename itr>
pair<bool,int> find(itr beg, itr end);
pair<bool,int> find(const char* str); template<typename itr>
bool DownNodeAlone(itr beg); template<typename itr>
bool erase(itr beg, itr end);
bool erase(const char* str); int sizeAll(pNode);
int sizeNodeRedundant(pNode); public:
pNode root;
private:
Type index;
}; template < int Size, typename Type>
template<typename itr>
void Trie<Size, Type>::insert(itr beg, itr end)
{
pNode cur = root, pre = NULL; for (; beg != end; ++beg)
{
if (!cur->ChildNode[index[*beg]])
{
cur->ChildNode[index[*beg]] = new(Node);
++cur->NodeSize;
}
pre = cur;
cur = cur->ChildNode[index[*beg]];
}
if (pre)
++pre->TerminableSize;
} template < int Size, typename Type>
void Trie<Size, Type>::insert(const char* str)
{
return insert(str, str + strlen(str));
} template <int Size, typename Type>
pair<bool, int> Trie<Size, Type>::find(const char* str)
{
return find(str, str + strlen(str));
} template <int Size, typename Type>
template<typename itr>
pair<bool,int> Trie<Size, Type>::find(itr beg, itr end)
{
pNode cur = root, pre = NULL;
pair<bool, int> res(false, );
for (;beg != end;++beg)
{
if (!cur->ChildNode[index[*beg]])
{
return res;
}
pre = cur;
cur = cur->ChildNode[index[*beg]];
}
if (pre != NULL&&pre->TerminableSize > )
{
res.first = true;
res.second = pre->TerminableSize;
}
return res;
} template <int Size, typename Type>
template<typename itr>
bool Trie<Size, Type>::DownNodeAlone(itr beg)
{
pNode cur = root;
int terminableSum = ; while (cur->NodeSize != )
{
terminableSum += cur->TerminableSize;
if (cur->NodeSize > )
return false;
else
{
for (size_t i = ; i < Size; i++)
{
if (cur->ChildNode[i])
{
cur = cur->ChildNode[i];
}
}
}
}
if (terminableSum == )
return true;
else return false;
} template <int Size, typename Type>
template<typename itr>
bool Trie<Size, Type>::erase(itr beg, itr end)
{
auto var = find(beg, end);
if (var.first)
{
pNode cur = root, pre = NULL;
for (; beg != end; ++beg)
{
if (DownNodeAlone(cur))
{
delete cur;
cur = NULL;
return true;
}
pre = cur;
cur = cur->ChildNode[index[*beg]];
}
if (pre->TerminableSize > )
--pre->TerminableSize;
return true;
}
return false;
} template <int Size, typename Type>
bool Trie<Size, Type>::erase(const char* str)
{
auto var = find(str);
if (var.first)
{
erase(str, str + strlen(str));
return true;
}
return false;
} template <int Size, typename Type>
int Trie<Size, Type>::sizeAll(pNode ptr)
{
if (ptr == NULL)
return ;
int rev = ptr->TerminableSize;
for (size_t i = ; i < Size; i++)
{
rev += sizeAll(ptr->ChildNode[i]);
}
return rev;
} template <int Size, typename Type>
int Trie<Size, Type>::sizeNodeRedundant(pNode ptr)
{
if (NULL == ptr)
return ;
int i, rev = ;
if (ptr->TerminableSize > )
rev = ;
if (ptr->NodeSize != )
{
for (i = ; i < Size; ++i)
{
rev += sizeNodeRedundant(ptr->ChildNode[i]);
}
}
return rev;
} template<int Size>
class Index
{
public:
Index() {}
~Index() {} public:
int operator[](char vchar)
{
return (vchar - 'a') % Size;
}
};

测试:

int main(void)
{
{
Trie<, Index<>> temp;
temp.insert("hello");
temp.insert("he");
temp.insert("he");
temp.insert("her");
temp.insert("him");
temp.insert("fuck");
temp.insert("fuckyou");
temp.insert("hupu");
temp.insert("lady");
temp.insert("hahah");
temp.insert("lady");
temp.insert("lady");
temp.insert("lady"); auto var = temp.find("lady");
cout << "lady:" << boolalpha <<var.first <<" "<<var.second<< endl;
var = temp.find("heihei");
cout << "heihei:" << boolalpha << var.first << " " << var.second << endl; cout << "size:" << temp.sizeAll(temp.root) << endl;
cout << "size of NoneRedundant:" << temp.sizeNodeRedundant(temp.root) << endl; var = temp.find("hupu");
cout << "hupu:" << boolalpha << var.first <<" "<<var.second<< endl;
temp.erase("hupu");
var = temp.find("hupu");
cout << "hupu:" << boolalpha << var.first << " " << var.second << endl; cout << "size:" << temp.sizeAll(temp.root) << endl;
cout << "size of NoneRedundant:" << temp.sizeNodeRedundant(temp.root) << endl;
} cin.get();
_CrtDumpMemoryLeaks();
return ;
}

字典树的C++实现的更多相关文章

  1. 萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)

    前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...

  2. [LeetCode] Implement Trie (Prefix Tree) 实现字典树(前缀树)

    Implement a trie with insert, search, and startsWith methods. Note:You may assume that all inputs ar ...

  3. 字典树+博弈 CF 455B A Lot of Games(接龙游戏)

    题目链接 题意: A和B轮流在建造一个字,每次添加一个字符,要求是给定的n个串的某一个的前缀,不能添加字符的人输掉游戏,输掉的人先手下一轮的游戏.问A先手,经过k轮游戏,最后胜利的人是谁. 思路: 很 ...

  4. 萌新笔记——C++里创建 Trie字典树(中文词典)(一)(插入、遍历)

    萌新做词典第一篇,做得不好,还请指正,谢谢大佬! 写了一个词典,用到了Trie字典树. 写这个词典的目的,一个是为了压缩一些数据,另一个是为了尝试搜索提示,就像在谷歌搜索的时候,打出某个关键字,会提示 ...

  5. 山东第一届省赛1001 Phone Number(字典树)

    Phone Number Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 We know that if a phone numb ...

  6. 字典树 - A Poet Computer

    The ACM team is working on an AI project called (Eih Eye Three) that allows computers to write poems ...

  7. trie字典树详解及应用

    原文链接    http://www.cnblogs.com/freewater/archive/2012/09/11/2680480.html Trie树详解及其应用   一.知识简介        ...

  8. HDU1671 字典树

    Phone List Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  9. *HDU1251 字典树

    统计难题 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others)Total Submi ...

  10. LA 3942 - Remember the Word (字典树 + dp)

    https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...

随机推荐

  1. 【转】以 java 为例,总结下 appium 里的一方法的使用心得

    转自:http://testerhome.com/topics/1043 1.关于没有name,没有ID的元素的定位---通用篇解题思路:因为没有name,id:其实剩下的选择已不多,要么xpath, ...

  2. python杂七杂八小问题

    1.win7系统下,安装完GTK+后,从命令行界面无法启动ipython,提示“failed to create process”.运行easy_install也遇到了这个问题. 原因是安装GTK+时 ...

  3. JavaScript高级程序设计-第六章面向对象的程序设计

    创建对象主要的两种形式,创建Object实例和创建对象字面量 对象包含属性和方法 数据 .属性有四个特性,特性是为了描述属性行为的,他们是: Configurable(可配置的)是否能删除或是否能修改 ...

  4. UVA 1395 (kruskal)

    /* 最大路与最小路的问题: 这道题看似简单,但是若不知道思路将无法写出. 思路:最小生成树很容易求出,但是最大值与最小值只差很难保证是最小的, 比如:1 5 5 6 100 101 很明显101 - ...

  5. java疑问-继承问题

    存在两个类,B 继承 A,C 继承 B,我们能将 B 转换为 C 么?如 C = (C) B:

  6. new 与 malloc 的区别

    1, 申请内存所在的位置 new 操作符从自由存储区上为对象动态分配内存空间,而 malloc 函数从堆上动态分配内存.自由存储区是C++基于 new 操作符的一个抽象概念,而堆是操作系统中的术语,是 ...

  7. 一种让超大banner图片不拉伸、全屏宽、居中显示的方法

    现在很多网站的Banner图片都是全屏宽度的,这样的网站看起来显得很大气.这种Banner一般都是做一张很大的图片,然后在不同分辨率下都是显示图片的中间部分.实现方法如下: <html> ...

  8. HYPER V 文件共享 复制文件 共享硬盘 来宾服务

    虚拟机的设置   -->  集成服务 –> 来宾服务  勾选    文件就可以在本地机器和虚拟机上来回复制了. 他可让 Hyper-V 管理员在运行虚拟机的同时将文件复制到虚拟机,且无需使 ...

  9. Centos 6.5 rsync+inotify 两台服务器文件实时同步

    rsync和inotify是什么我这里就不在介绍了,有专门的文章介绍这两个工具. 1.两台服务器IP地址分别为: 源服务器:192.168.1.2 目标服务器:192.168.1.3 @todo:从源 ...

  10. Yii2 利用controllerMap自定义控制器类

    版权声明:本文为博主原创文章,未经博主允许不得转载. Yii2框架为我们自定义好的  controllers,Models,views,标准的MVC结构框架,但是有些时候我们写接口希望结构更加清晰而不 ...