字典树原理--利用map实现

        字典树用于统计次数、在一堆字符串中查找特定字符串等环境中,效率较高。通常从根节点开始,每个节点存入字符,该字符的下层节点仍然有一个map,用于存放第二个节点的字符,以此类推。

        如图的字典树,有两个字符串,abd和ac。当然,可以在每个节点上增加结束标识,用于标识他也是一个完整的字符串。比如,在b节点的表示字段上标识结束,那么就有三个字符串,ab,ac和abd。

//字典树
struct stNode
{
	bool bOver = false;    //是否可以结束节点
	std::map<char, stNode*> m_mapNode;  //下层节点
};
int main()
{
	std::vector<std::string> veVal = {"qwe", "qsd", "qsda", "aer"};
	stNode *pstHead = new stNode();
	for (auto &it : veVal)
	{
		stNode *pstNode = pstHead;
		for (int i = 0; i < it.size(); ++i)
		{
			bool bOver = i == it.size() - 1 ? true : false;
			auto itfind = pstNode->m_mapNode.find(it.at(i));
			if(itfind == pstNode->m_mapNode.end())
			{
				stNode *pstTmp = new stNode();
				pstNode->m_mapNode.insert(std::make_pair(it.at(i), pstTmp));
				itfind = pstNode->m_mapNode.find(it.at(i));
				if (bOver)
					pstNode->bOver = true;
				pstNode = pstTmp;
				cout << "11111111111 " << it.at(i) << endl;
			}
			else
			{
				if (bOver)
					pstNode->bOver = true;
				pstNode = itfind->second;
				cout << "22222222222 " << it.at(i) << endl;
			}
		}
	}
	std::string strInfo = "aer";
	stNode *pstInfo = pstHead;
	for (int i = 0; i < strInfo.size(); ++i)
	{
		auto itfind = pstInfo->m_mapNode.find(strInfo.at(i));
		if (itfind == pstInfo->m_mapNode.end())
		{
			cout << "no" << endl; //找不到
			break;
		}
		if (i == strInfo.size() - 1)
		{
			if (pstInfo->bOver)
			{
				cout << "yes" << endl; //找到
			}
			else
			{
				cout << "hhh" << endl; //字符存在 长度小于匹配长度
			}
		}
		pstInfo = itfind->second;
	}
	return 0;
}

        原本项目中的代码使用大量if elseif进行判断,但是当量较大时,if elseif采用依次遍历的方式比较,效率较低。但是switch天生不支持字符串的比较,也确实比较麻烦。关于if else和switch的区别,switch case实际上是维系了一个连续的内存空间,类似于数组,每次对比一个值,先判断是否超过最大数组下标,没有超过就直接用数组去调用。以空间换时间。当然,如果数值中间跨度较大的时候,不建议采用。例如,case 1:    case 100:    case 108,这样的语句建议使用if else。同理,如果我们一定要比较字符串,可以先手工哈希一次,这样就可以借助switch case来比较。

         优缺点:

                    if elseif 可能需要遍历所有的分支查找,switch case因为生成了查找表,所以不用遍历,效率较高。

                    if elseif 允许任何情况的查找,switch case在查找分支相差较大的时候,浪费空间。例如,case 1: case 100:实际生成了101位的跳转表。

                     if elseif 允许非常量查找,switch case不支持。例如,if (10 < x && x < 100)

        if elseif在多分支的时候,效率比较低,并且是逐个比较,因为在日常的代码编写过程中应当人为有意的,尽量将可能满足的分支写在靠前面的地方。虽然分支较多的时候效率较低,但是if elseif的应用场景更加灵活。switch case内部以空间换时间,在查找上效率更高。对比看来,在很多情况下,字典树是一种比较好的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值