/*************************************************************************
> 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
ip search
最新推荐文章于 2024-04-21 16:22:38 发布