算法(25)-前缀树(2)-添加-查找-返回以某字符为首的查找个数-C++

前缀树三个主要的函数:
                                           1.添加word void insert(string word)
                                           2. 查询是否在字典树中 bool search(string word)
                                           3.返回以字符串pre为前缀的单词数量 int prefixNumber(string pre):

用前缀树很重要的一点是可以查找以“pre”,就是某些字母开头的,不然就用哈希表,或者其它的词频统计方式。
直接上代码吧。
 

//英文字母不区分大小写是26叉树,数字是10叉树
const int MaxNum = 26;
// 数组方式
class TrieNodeArr{
public:
	int pass;
	int end;
	TrieNodeArr* nexts[MaxNum];          //此处为指向下一个Node的指针 

	TrieNodeArr()
	{
		pass = 0;
		end = 0;
		for (int i = 0; i < MaxNum; i++)   //构造函数不用new
		{
			nexts[i] = NULL;
		}
		//如果字符全是小写 nexts 下级对应的路的位置 a-z 26个字母
        //0-a ...25-z
		//nexts[0]==NULL;表示没有走向a的路。
		//nexts[0]!=NULL;表示有走向a的路。
		//...
	}
	
};
//1.root 为指针
class Trietree
{
public:	
	 Trietree();
	~Trietree();
	TrieNodeArr *root;

	void insert(string word);
	void myDeleteJAVA(string word);
	bool mysearch(string word);
	int prefixNumber(string word);
	void destory(TrieNodeArr* node);
	void myDeleteCPP(string word);

	
};
Trietree::Trietree()
{
	root = new TrieNodeArr();
}
Trietree::~Trietree()
{
	destory(root);
}
void Trietree::destory(TrieNodeArr* node)
{
	if (node == nullptr)
		return;
	for (int i = 0; i < MaxNum; i++)
	{
		destory(node->nexts[i]);
	}
	delete node;
	node = nullptr;
}
// 1.遍历字符串
//2. 查map ,ARR  新建
//3. 继续往下走
void Trietree::insert(string word)
{
	cout << "Trietree  insert******************" << endl;
	if (word ==""){		return;	}               //1.插入字符为空 返回
	char c;
	int path = 0;
	TrieNodeArr *node=root;                     //2.取得根结点
	for (int i = 0; i < word.length(); i++)     //3.遍历字符串
	{
		char c = word[i];                        //4.得到单个字符
		c = c - 'a';                             //5.是哪条路
		if (node->nexts[path] == nullptr)        //6 如果没有 创建新的路
		{
			node->nexts[path] = new TrieNodeArr();//7.新建路
		}
		node = node->nexts[path];                 //8.node移到下一个节点
		node->pass++;                             //9.pass+1 表示走过一次
	}
	node->end++;                                  //10.一个字符添加完了,e+1
}
bool Trietree::mysearch(string word)
{
	cout << "Trietree  search******************" << endl;
	int m_num = 0;
	if (word == "") { return 0; }                  //1.字符为空 返回
	char c;
	int path = 0;
	TrieNodeArr* node = root;                     //2.取得根结点
	for (int i = 0; i < word.length(); i++)       //3.遍历字符串
	{
		char c = word[i];                        //4.得到单个字符
		c = c - 'a';                             //5.是哪条路
		if (node->nexts[path] == nullptr)        //6 如果没有路
		{
			return 0;
		}
		node = node->nexts[path];                 //7.node移到下一个节点
   
	}
	if (node != nullptr)                         //8.如果有下一个节点,返回本节点的e值
	{
		return node->end;
	}
	else
	{
		return 0;                                   //树上没有这个节点,返回0值,一般出现在树“abc”,而实际查询的是“abcdef”            
	}
	return node->end != 0;
	
}
//加入的字符串,有多少是以pre为前缀的
int Trietree::prefixNumber(string pre)
{
	cout << "Trietree  prefixNumber******************" << endl;
	int m_num = 0;
	if (pre == "") { return 0; }               //1.字符为空 返回
	char c;
	int path = 0;
	TrieNodeArr* node = root;                     //2.取得根结点
	for (int i = 0; i < pre.length(); i++)     //3.遍历字符串
	{
		char c = pre[i];                        //4.得到单个字符
		c = c - 'a';                             //5.是哪条路
		if (node->nexts[path] == nullptr)        //6 如果没有 
		{
			return 0;
		}
		node = node->nexts[path];                 //7.node移到下一个节点
	}	
	return node->pass;                            //8.返回的是本节点上p的值
}
void Trietree_main()
{	
	cout<<"Trietree******************"<<endl;
		
	Trietree trie;
	string str = "li";
	cout << trie.mysearch("abc")<< endl;
	trie.insert("abc");
    trie.insert("abcw");
    trie.insert("abce");
	trie.insert("abc");
	trie.insert("abcr");
	trie.insert("abco");
	cout << trie.mysearch("abcw") << endl;
	cout << trie.prefixNumber("abc") << endl;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值