ip search

/*************************************************************************
    > File Name: TrieMap.h
    > Author: wangzhicheng
    > Mail: 2363702560@qq.com
    > Created Time: 2017-01-29
    > statement: 用于加速查找过程的TrieMap类 key -- 最好是由数字 英文字母组成的字符串
 ************************************************************************/
#ifndef _TRIE_MAP_H_
#define _TRIE_MAP_H_
#include <stdio.h>
#include <string.h>
#include <vector>
namespace triemap
{
using namespace std;
enum NodeType 	 // 0 - 中间结点 1 - 终端结点
{
	UNCOMPLETED,
	COMPLETED
};	
static const int S_TRIE_N = 256;			    // 指针域中指针个数 与ASCII码对应
/*
 * @brief 结点类
 * */
template<class ValueType>
class TrieNode
{
public:
	ValueType m_Value;			// 与key关联的value
	NodeType m_Type;			// 0 or 1
	TrieNode *m_pChildren[S_TRIE_N];		

	TrieNode()
	{
		m_Type = UNCOMPLETED;
		memset(m_pChildren, 0, S_TRIE_N * sizeof(TrieNode *));
	}
};
/*
 * @brief TrieMap类 
 * */
template<class ValueType>
class TrieMap
{
private:
	TrieNode<ValueType>*m_pRoot;		        	// 根结点
	vector<TrieNode<ValueType>*>m_vecNodeAddrs;	    // 保存终端的地址 用于遍历
	/*
	 * @brief 创建一个新结点
	 * */
	inline TrieNode<ValueType>*NewTrieNode()
	{
		TrieNode<ValueType>*p = new TrieNode<ValueType>;
		return p;
	}
	/*
	 * @brief 递归删除ptr所执向结点
	 * */
	void Delete(TrieNode<ValueType>*&ptr);
public:
	/*
	 * @brief 构建根结点
	 * */
	TrieMap();
	~TrieMap();
	/*
	 * @brief 插入一个新结点
	 * */
	void Insert(const char *key, const ValueType &value);
	/*
	 * @brief 查找结点
	 * @key 要查询的key
	 * @value 与key关联的值
	 * @return 查找成功返回true 不成功返回false
	 * */
	bool Find(const char *key, ValueType &value);
	/*
	 * @brief 查找结点
	 * @key 要查询的key
	 * @status 如果函数返回的指针指向终端结点 那么status为true 中间结点返回false
	 * @return 查找成功返回指向TrieNode *的指针(此时返回指针可能指向终端结点或中间结点 取决于key) 查找失败返回NULL
	 * */
	TrieNode<ValueType>*Find(const char *key, bool &status);
	/*
	 * @brief 查找结点
	 * @key 要查询的key
	 * @status 如果函数返回的指针指向终端结点 那么status为true 中间结点返回false
	 * @return 查找成功返回指向TrieNode *的指针(此时返回指针可能指向终端结点或中间结点 取决于key) 查找失败返回NULL
	 * */
	TrieNode<ValueType>*Find(const char *key, TrieNode<ValueType>*startPtr, bool &status);
	/*
	 * @brief 取得所有终端结点的value 
	 * */
	void GetValues(vector<ValueType *>&vecOut);
	/*
	 * @brief 判断TrieMap是不是为空
	 * @return 为空返回true 不空返回false
	 * */
	bool Empty() const;
};//ns
template<class ValueType>
TrieMap<ValueType>::TrieMap()
{
	m_pRoot = new TrieNode<ValueType>;
}
template<class ValueType>
void TrieMap<ValueType>::Insert(const char *key, const ValueType &value) 
{
	TrieNode<ValueType>*ptr = m_pRoot;
	int pos;
	for(int i = 0;key[i];i++) {
		pos = key[i];
		if(!ptr->m_pChildren[pos]) {
			ptr->m_pChildren[pos] = NewTrieNode();	// 耗时
		}
		ptr = ptr->m_pChildren[pos];
	}
	ptr->m_Type = COMPLETED;
	ptr->m_Value = value;
	m_vecNodeAddrs.push_back(ptr);				// 保存终端结点
}
template<class ValueType>
bool TrieMap<ValueType>::Find(const char *key, ValueType &value) 
{
	TrieNode<ValueType>*ptr = m_pRoot;	 // 从根结点开始查
	int pos;
	int i;
	for(i = 0;key[i];i++) {
		pos = key[i];
		if(!ptr->m_pChildren[pos]) break;
		else ptr = ptr->m_pChildren[pos];
	}
	if(!key[i] && (COMPLETED == ptr->m_Type)) {
		value = ptr->m_Value;
		return true;
	}

	return false;
}
template<class ValueType>
TrieNode<ValueType>*TrieMap<ValueType>::Find(const char *key, bool &status) 
{
	TrieNode<ValueType>*ptr = m_pRoot;	// 从根结点开始查
	int pos;
	int i;
	for(i = 0;key[i];i++) {
		pos = key[i];
		if(!ptr->m_pChildren[pos]) break;
		else ptr = ptr->m_pChildren[pos];
	}
	if(!key[i]) {
		if(ptr->m_Type == COMPLETED) status = true;	// 终端结点
		else status = false;						// 中间结点
		return ptr;
	}

	return NULL;
}
template<class ValueType>
TrieNode<ValueType>*TrieMap<ValueType>::Find(const char *key, TrieNode<ValueType>*startPtr, bool &status) 
{
	int pos;
	int i;
	TrieNode<ValueType>*ptr = startPtr;	// 从指定结点开始查
	if(!ptr) return NULL;
	for(i = 0;key[i];i++) {
		pos = key[i];
		if(!ptr->m_pChildren[pos]) break;
		else ptr = ptr->m_pChildren[pos];
	}
	if(!key[i]) {
		if(ptr->m_Type == COMPLETED) status = true;     // 终端结点
		else status = false;  
		return ptr;
	}

	return NULL;
}
template<class ValueType>
void TrieMap<ValueType>::Delete(TrieNode<ValueType>*&ptr) 
{
	int i;
	if(!ptr) return;
	for(i = 0;i < S_TRIE_N;i++) {
		if(ptr->m_pChildren[i]) Delete(ptr->m_pChildren[i]);
	}
	// 到此处 ptr所有的子孩子都已经访问过 删除ptr所指向结点
	if(ptr) {
		delete ptr;
		ptr = NULL;
	}       
}
template<class ValueType>
void TrieMap<ValueType>::GetValues(vector<ValueType *>&vecOut) 
{
	int i, size;
	size = m_vecNodeAddrs.size();
	vecOut.resize(size);
	for(i = 0;i < size;i++) vecOut[i] = &m_vecNodeAddrs[i]->m_Value;
}
template<class ValueType>
bool TrieMap<ValueType>::Empty() const 
{
	bool empty_flag = true;
	int i;
	for(i = 0;i < S_TRIE_N;i++) {
		if(m_pRoot->m_pChildren[i]) {
			empty_flag = false;
			break;
		}
	}
	
	return empty_flag;
}
template<class ValueType>
TrieMap<ValueType>::~TrieMap() 
{
	if(m_pRoot) Delete(m_pRoot);
}
}
#endif

/****************************************************************************
@File Name: test.cpp
@Author: wangzhicheng
@mail: 2363702560@qq.com
@Created Time: Sun 29 Jan 2017 08:26:47 PM CST
****************************************************************************/
#include "TrieMap.h"
#include <iostream>
#include <string>
using namespace triemap;
int main()
{
	TrieMap<string>trieMap;
	trieMap.Insert("192.168.0.1", "L0");
	trieMap.Insert("192.168.0.2", "L1");
	trieMap.Insert("192.168.0.3", "L2");
	trieMap.Insert("192.168.10.1", "L3");
	trieMap.Insert("192.168.10.10", "L4");
	trieMap.Insert("192.168.120.0", "L5");
	trieMap.Insert("192.168.133.18", "L6");
	trieMap.Insert("192.168.138.111", "L7");
	string ip;
	string L;
	cin >> ip;
	if(trieMap.Find(ip.c_str(), L))
	{
		cout << L << endl;
	}

	return 0;
}

CC=g++
all:
	$(CC) -std=c++11 -g -o test test.cpp TrieMap.h

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值