笔试题之 ip 快速查找

69 篇文章 0 订阅
60 篇文章 3 订阅

笔试题之去哪:ip快速查找

个人信息:就读于燕大本科软件工程专业 目前大三;

本人博客:google搜索“cqs_2012”即可;

个人爱好:酷爱数据结构和算法,希望将来搞科研为人民作出自己的贡献;

博客内容:笔试题之去哪:ip快速查找;

博客时间:2014-3-29

编程语言:C++

编程坏境:Windows

编程工具:vs2008

 

  • 引言

突然发现去哪的笔试题很有共性,好像每一次笔试题,都有一个大型数据文件,然后让根据大型文件计算或者查找某个关键字。这种考题个人感觉回落在折半查找,哈希,trie树上等等。

  • 题目

    • 9月24日,去哪儿网2014校招西安站笔试题
      给定一个200MB的文本文件,里面存的是IP地址到真实地址信息的映射信息,例如:211.200.101.100北京
      然后给你6亿个IP地址,请设计算法快速的打印出所对应的真实地址信息。

  • 思路

个人感觉此题从大方向上会用到tire树,接着从trie树每个节点上会用到折半查找。个人设计数据结构如下

个人整体思路是

1.将文本信息读到内存中,每读一条ip信息就插入到trie tree中,在插入过程中,会遇到查找操作,这时候选择折半查找就好;

2.整个trie tree的高度都是3;

3.整个trie tree是一颗高度平衡树,即每个叶子到根节点的长度都是4;

4.整个算法会有好多棵这样的树,每一个ip的前三位数字会作为一棵树的根,如果已经包含这样根的树,直接插入就好,否则建立新树;

 

  • 实验

实验有两部分:

1.随机生成一个文本信息 ip个数 1000,000;

2.读取文本,然后插入trie tree 中;

3.输入关键字;

4.在trie trees中进行查询;

5.返回结果;

6.每一步程序执行之后,都是耗时显示;

7.建立文本速度还行,建立trie trees 耗时很长,查询非常快,快的不得了;

程序结果截图如下

文本说明 20m,为什么不用200m,还有一些问题,稍后解决给出问题,致bad alloc问题,请谅解,谢谢。

  • 代码

mine_string.h

#include <iostream>
#include <string>
#include <limits>
using namespace std;

// extra the class of string
class String:public string
{
public:

	// function 1: mode the add of int( (-3) + (-3) ) = - 6
	// input: 两个字符串 a 和 b,里面放的都是整数;
	// output: 返回一个字符串,字符串里面是整数;
	// 功能: 实现参数两个整数的相加操作,结果存在返回的字符串里
	static string ADD_Int(string a,string b);



	// function 2: make a-b mode int a - b; 7 - (-3) = 10
	// input: 两个字符串 a 和 b,里面放的都是整数;
	// output: 返回一个字符串,字符串里面是整数;
	// 功能: 实现参数两个整数的相减操作,结果存在返回的字符串里
	static string MINUS_Int(string a,string b);

	// function 3: make a*b mode int a * b;
	// input: 两个字符串 a 和 b,里面放的都是整数;
	// output: 返回一个字符串,字符串里面是整数;
	// 功能: 实现参数两个整数的相乘操作,结果存在返回的字符串里
	static string MULT_Int(string a,string b);

	// function 4: mode the division a/b
	// input: 两个字符串 a 和 b,里面放的都是整数;
	// output: 返回一个字符串,字符串里面是整数;
	// 功能: 实现参数两个整数的相除操作,结果存在返回的字符串里
	static string DIV_Int(string a,string b);

	// function 5: pow number a^b
	// input: 两个字符串 a 和 b,里面放的都是整数;
	// output: 返回一个字符串,字符串里面是整数;
	// 功能: 实现参数两个整数的a^b操作,结果存在返回的字符串里
	static string Pow_Int(string a,string b);

	// function 6: int To string :"123" = 123
	// input: 一个int数 a;
	// output: 返回一个字符串,字符串里面是整数;
	// 功能: 将整数a转换成对应的字符串格式
	static string Int_To_String(int x);

	// function 7: static char division a/b : 4 / 3
	static string Division(string a,string b);

	// function 8: make a-b mode int a - b; 4 - 3
	static string MinusInt(string a,string b);

	// function 9: mode the add of int :3 + 4
	static string AddInt(string a,string b);

	// function 10: make char to the int number :'9' = 9
	static int CharToNumber(char c);

	// function 11: make int to the model char : 7 = '7'
	static string IntToChar(int i);

	// function 12: check whether the string is legal 
	static bool check_all_number(string a);

	// function 13: compare string a and b
	// input: 两个字符串 a 和 b,里面放的都是整数;
	// output: 返回一个字符,字符里是a和b的大小关系;
	// 功能: 实现参数两个整数的a和b比较操作,结果< or = or >存在返回的字符里
	static char Compare(string a,string b);

	// function 14: make string into standard string number
	static bool Standardization(string &a);

	// function 15: make string(>0) into standard int number
	// input: 一个字符串 a,里面放的是一个整数;
	// output: 返回一个字符串,字符串里是a对应的整形数据;
	// 功能: 将存在字符串里的整数取出来,放在整形容器里,然后返回,根据返回的结果可以判定是否转换成功
	static std::pair<bool,int> String_into_intNumber(string &a);
};



// mode the add of int
string String::ADD_Int(string a,string b)
{
	// exception of input
	if( a.empty() )
		return b;
	else if( b.empty() )
		return "0";
	if(!check_all_number(a) || !check_all_number(b))
	{
		return "exception of input ADD_Int";
	}
	Standardization(a);
	Standardization(b);	

	if(a[0] != '-' && b[0] != '-')
		return AddInt(a,b);
	else if(a[0] != '-'&& b[0] == '-')		
		return MinusInt( a,b.substr( 1,b.size() ) );
	else if(a[0] == '-'&& b[0] != '-')
		return MinusInt(b,a.substr(1,a.size()));
	else return '-'+AddInt(a.substr(1,a.size()),b.substr( 1,b.size() ));
};







// make a-b mode int a - b;
string String::MINUS_Int(string a,string b)
{
	// exception of input
	if( a.empty() )
		return b;
	else if( b.empty() )
		return "0";
	if(!check_all_number(a) || !check_all_number(b))
	{
		return "exception of input Multiplies_Int";
	}
	Standardization(a);
	Standardization(b);	
	if(a[0] != '-' && b[0] != '-')
		return MinusInt(a,b);
	else if(a[0] != '-' && b[0] == '-')
		return AddInt(a,b.substr(1,b.size()));
	else if(a[0] == '-' && b[0] != '-')
		return "-"+AddInt(a.substr(1,a.size()),b);
	else return MinusInt( b.substr(1,b.size()) , a.substr(1,a.size()) );
};






// make a*b mode int a * b;
string String::MULT_Int(string a,string b)
{
	// exception of input
	if( a.empty() )
		return b;
	else if( b.empty() )
		return "0";
	if(!check_all_number(a) || !check_all_number(b))
	{
		return "exception of input Multiplies_Int";
	}
	Standardization(a);
	Standardization(b);	
	string::size_type i = a.size(),j = b.size();
	string c = "0",d = "";
	bool fushu = (a[0] == '-' && b[0] != '-')||(a[0] != '-' && b[0] == '-');
	if(a[0] == '-')	
		a = a.substr(1,a.size());		
	if(b[0] == '-')	
		b = b.substr(1,b.size());

	int jinwei = 0;
	for( j = b.size()-1 ; j < b.size() ;j--)
	{
		// each number of b to * a 
		jinwei = 0;
		for( i = a.size()-1 ; i < a.size() ;i-- )
		{
			d = IntToChar(   ( CharToNumber(a[i]) * CharToNumber(b[j]) + jinwei ) % 10 )+ d ;
			jinwei = ( CharToNumber(a[i]) * CharToNumber(b[j]) + jinwei ) / 10 ;
		}
		if(jinwei)
			d = IntToChar(jinwei) +d;
		// add all number result
		c = ADD_Int(c,d);
		d = "";
		unsigned int zero = 0 ;
		while( zero < b.size() - j )
		{
			d = d + '0';
			zero ++;
		}

	}

	Standardization(c);
	if( fushu && c != "0" )
		return '-'+c;
	else return c;
};




// mode the division a/b
string String::DIV_Int(string a,string b)
{
	// exception of input
	if( a.empty() )
		return "0";
	else if( b.empty() )
		return "e";
	if(!check_all_number(a) || !check_all_number(b))
	{
		return "exception of input DIV_Int";
	}
	Standardization(a);
	Standardization(b);	
	if(b == "0")
		return "e";
	bool fushu =  (a[0] == '-' && b[0] != '-')||(a[0] != '-' && b[0] == '-');
	if( a[0] == '-' )	
		a = a.substr(1,a.size());		
	if( b[0] == '-' )	
		b = b.substr(1,b.size());
	if( Compare(a,b) == '<' )
		return "0";


	string yushu = "";

	string beichushu = a.substr(0,b.size());	
	string shang = Division( beichushu , b);
	yushu =  MinusInt( beichushu ,MULT_Int( shang, b) );
	string c = shang;

	for(string::size_type i = b.size(); i<a.size(); i++)
	{	
		beichushu =   yushu+ a[i]     ;
		shang = Division( beichushu , b);
		c = c + shang;			
		yushu =  MinusInt( beichushu ,MULT_Int( shang, b) );
	}
	Standardization(c);
	return fushu?('-'+c):c;
};





// function: pow number x,y
string String::Pow_Int(string a,string b)
{
	// exception of input
	if( a.empty() )
		return "0";
	else if( b.empty() )
		return "e";
	if(!check_all_number(a) || !check_all_number(b))
	{
		return "exception of input DIV_Int";
	}
	Standardization(a);
	Standardization(b);	
	string result = "1" ;
	if(Compare(b,"0") != '<')
		for(string i ="0" ;Compare(i,b) == '<' ;i = AddInt(i,"1"))
		{
			result = MULT_Int(result,a);
		}
	else 
		for(string i ="0" ;Compare(i,b) == '>' ;i = MINUS_Int(i,"1"))
		{
			result = DIV_Int(result,a);
		}
		return result ;
};






// function : int To string 
string String::Int_To_String(int x)
{
	bool fushu = false;
	string result="";
	if(x < 0 )
	{
		fushu = true ;
		x = -x;
	}
	else if( x == 0 )
		return "0";
	while(x)
	{
		result = IntToChar(x % 10) + result;
		x = x/10;
	}
	if(fushu)
		result = "-"+result;
	return result;
};





// static char division a/b
string String::Division(string a,string b)
{
	// exception of input
	if( a.empty() )
		return "0";
	else if( b.empty() )
		return "e";
	if(!check_all_number(a) || !check_all_number(b))
	{
		cout<<"exception of input Division"<<endl;
		return "e";
	}
	Standardization(a);
	Standardization(b);	
	int i = 0;
	while( i<=9 )
	{
		// if a - b*i < b
		if(  Compare(   MINUS_Int(   a  ,   MULT_Int(IntToChar(i),b)    ) , b ) == '<'    )
			break;
		i++;
	}
	if( i>9 )
		return "e";
	return ""+IntToChar(i);
};






// make a-b mode int a - b;
string String::MinusInt(string a,string b)
{
	// exception of input
	if(!check_all_number(a) || !check_all_number(b))
		return "exception of input MinusInt";
	Standardization(a);
	Standardization(b);
	// particular string of input
	if(a.empty())
	{
		if(b.empty())
			return "0";
		else
			return "-"+b;
	}
	else if(b.empty())
	{
		return a;
	}

	// normal number a < b
	string c = "";
	bool check = true ;
	if(Compare(a,b) == '=')
		return "0";
	else if(Compare(a,b) == '<')
	{
		c = a ;
		a = b ;
		b = c ;
		c = "";
		check = false ;
	}
	// normal number a >= b
	string::size_type i = a.size()-1, j = b.size()-1;
	int jiewei = 0,now;

	while(i < a.size() && j < b.size())
	{
		now = CharToNumber(a[i]) - CharToNumber(b[j]) - jiewei ;

		if( now < 0 )
		{
			jiewei = 1;
			now = 10 + now ;
		}
		else jiewei = 0;
		c = IntToChar(now)  + c ;
		i--;j--;
	}
	while(i < a.size())
	{
		now = CharToNumber(a[i]) - jiewei ;
		if( now < 0 )
		{
			jiewei = 1;
			now = 10 + now ;
		}
		else jiewei = 0;
		c = IntToChar( now )  + c ;
		i--;
	}
	Standardization(c);
	if(!check)
		c = '-' + c;		
	return c; 
};







// mode the add of int
string String::AddInt(string a,string b)
{
	// exception of input
	if( a.empty() )
		return b;
	else if( b.empty() )
		return "0";
	if(!check_all_number(a) || !check_all_number(b))
	{
		return "exception of input AddInt";
	}
	Standardization(a);
	Standardization(b);
	string::size_type i = a.size()-1 ,j = b.size()-1 , k = 0 ;
	string c = "";
	int jinwei = 0;
	while( i < a.size() && j < b.size() )
	{
		c = IntToChar( ( CharToNumber(a[i]) + CharToNumber(b[j]) + jinwei ) % 10 ) + c;
		jinwei = ( CharToNumber(a[i]) + CharToNumber(b[j]) + jinwei ) / 10;
		j--;i--;
	}
	while( j < b.size()  )
	{
		c =  IntToChar( ( CharToNumber(b[j]) + jinwei ) % 10 ) + c;
		jinwei = ( jinwei + CharToNumber(b[j]) ) / 10;	
		j--;
	}
	while( i < a.size() )
	{
		c =  IntToChar( ( CharToNumber(a[i]) + jinwei ) % 10 ) + c;
		jinwei = ( jinwei + CharToNumber(a[i]) ) / 10;	
		i--;
	}
	if( jinwei )
		c = IntToChar(  jinwei  ) + c;
	Standardization(c);
	return c;
};







// make char to the int number
int String::CharToNumber(char c)
{
	if( c >= '0' && c <= '9' )
		return int(c - '0');
	else 
	{
		cout<<c<<" exception of input CharToNumber "<<endl;
		system("pause");
		return 0;
	}
};







// make int to the model char
string String::IntToChar(int i)
{
	if( i >= 0 && i <= 9 )
	{
		string c = "";
		return c+char(i+48);
	}
	else
	{
		cout<<i<<" exception of input IntToChar"<<endl;
		system("pause");
		return "e";
	}
};






// check whether the string is legal 
bool String::check_all_number(string a)
{
	if(a.empty())
		return true ;
	string::size_type L = a.size(),i = 0;
	if(a[0] == '-')
		i++;
	while( i < L )
	{
		if( a[i] < '0' || a[i] > '9')
			return false;
		i++; 
	}
	return true ;
};







// compare string a and b
char String::Compare(string a,string b)
{
	if(a.empty() || b.empty())
	{
		cout<<"error of input compare";
		return 'e';
	}
	else
	{

		if(!check_all_number(a) || !check_all_number(b))
		{
			return 'e';
		}
		Standardization(a);
		Standardization(b);
		if(a[0] == '-' && b[0] != '-')
			return '<';
		else if( a[0] != '-' && b[0] == '-')
			return '>';
		bool fushu = (a[0] == '-');

		if(a.size() > b.size() )
			return fushu?'<':'>';
		else if(a.size() == b.size())
		{
			for(string::size_type i = 0;i < a.size(); i++)
			{
				if(a[i] > b[i])
					return fushu?'<':'>';
				if(a[i] < b[i])
					return fushu?'>':'<';
			}
			return '=';
		}			
		return fushu?'>':'<';
	}
};







// make string into standard string number
bool String::Standardization(string &a)
{
	if(!check_all_number(a))
	{
		cout<<a<<" exception of input Standardization"<<endl;
		return false;
	}
	string::size_type i = 0;
	bool fushu = false ;
	if( a[0] == '-' )
	{
		fushu = true;
		i = 1;
	}
	while(i < a.size())
	{
		if(a[i] != '0')
			break;
		i++;
	}
	if(i == a.size())
		i--;
	a = a.substr(i,a.size());
	if( fushu && a != "0")
		a = '-' + a;
	return true ;
};







// make string(>0) into standard int number
std::pair<bool,int> String::String_into_intNumber(string &a)
{
	if(Standardization(a))
	{
		//int max_int = numeric_limits<int>::max()-1 ;
		//string max = Int_To_String(max_int);
		bool fushu = false;
		if(a[0] == '-')
		{
			fushu = true ;
			a = a.substr(1,a.length());
		}
		//if(Compare(a,max) != '<')
		//{
		//	cout<<"溢出 exception"<<endl;
		//	return std::make_pair(false,0);
		//}
		int result = 0 ;
		for(size_t i =0;i<a.length();i++)
		{
			result = result * 10 + CharToNumber(a[i]);
		}
		if(fushu)
			result = - result;
		return std::make_pair(true,result);
	}
	else
	{
		cout<<"exception of function String_into_intNumber input"<<endl;
		return std::make_pair(false,0);
	}
};


test.cpp

// include head file

#include<fstream>
#include<vector>
#include<iterator>
#include<Windows.h>
#include<utility>
#include"mine_string.h"



// myclass
class trie_leaf
{
public:
	int key;
	string place;
	trie_leaf()
	{
		key = -1;
		place = "NULL";
	}
};

class trie_node
{
public:
	int key;
	vector<trie_node*>  *child ;
	vector<trie_leaf*>  *leaf ;
	trie_node(){
		key = -1 ;
		child = NULL ;
		leaf = NULL ;
	}
};

// function: make file
// input: a size_t number,standing ip ziduan number
// output: a file("ip.txt"), which including all the ip data
// 功能: 随机生成一个file("ip.txt"),里面存储模拟生成的ip地址
void _Make_ip_file(size_t size);

// function: read data;
// input: a file("ip.txt"), which including all the ip data;
// output: a trie tree root point
// 功能: 将文件数据读到内存中,存在好多个 trie trees 中
vector<trie_node*>* ip_data_read();

// function: binary_search
// input: a trie node and ip keyword
// output: the pair<bool,int>,if bool true, and find keyword; or not find = false
// 功能: 在指定节点中,查找关键字,若能找到返回<true,下标>;否则返回<false,应该插入的下标>
std::pair<bool,int> binary_search(vector<trie_node*> *tree,int key);

// function: binary_search leaf
// input: a trie leaf and ip keyword
// output: the pair<bool,int>,if bool true, and find keyword; or not find = false
// 功能: 在指定叶子中,查找关键字,若能找到返回<true,下标>;否则返回<false,应该插入的下标>
std::pair<bool,int> binary_search_leaf(vector<trie_leaf*> *tree,int key);

// function: insert keyword into trie tree
// input: a trie node and ip information
// output: void
// 功能:将 ip 信息插入到当前 trie 节点中
void insert_into_trie(vector<trie_node*> *tree,int *data,int length,string place);

// function: _Trie_tree_visit
// input:a trie tree' root point
// output:void
// 功能: 遍历 trie 树
void _Trie_tree_visit(vector<trie_node*> *tree,int level);

// function: _Trie_tree_visit
// input:a trie tree' root point
// output:void
// 功能: 遍历 trie 树的叶子
void _Trie_tree_visit_leaf(vector<trie_leaf*> *tree,int level);

// function: ip binary search
// input: a trie tree and a keyword key
// output: return pair<bool,string>
// 功能:折半查找ip,返回其信息
std::pair<bool,string> _Ip_binary_search(vector<trie_node*>* tree,string key);

// function: delete the space we used;
// input: a trie tree root point vector point, and level
// output: void
// 功能: 释放掉我们开辟的空间,节省空间资源
void _delete_trie_tree(vector<trie_node*>* tree,int level);



// function: main
int main()
{
	DWORD s,e;

	string ip ;
	std::pair<bool,string> r;
	vector<trie_node*>* tree;
	//int i=1000;
	//while(i <= 10000000)
	//{
	//	s = GetTickCount();
	//	_Make_ip_file(i);
	//	e = GetTickCount();
	//	cout<<"data number = "<<i<<endl;
	//	cout<<"file write= "<<e-s<<endl;

	//	s = GetTickCount();
	//	tree = ip_data_read();
	//	e = GetTickCount();
	//	//_Trie_tree_visit(tree,0);
	//	cout<<"file read= "<<e-s<<endl;

	//	cout<<"请输入ip信息如下 123.123.123.222"<<endl;
	//	cin>>ip;
	//	while(ip != "over")
	//	{	
	//		s = GetTickCount();
	//		r = _Ip_binary_search(tree,ip);
	//		e = GetTickCount();
	//		cout<<"result = "<<r.second<<endl;
	//		cout<<"ip search = "<<e-s<<endl;
	//		cout<<"请输入ip信息如下 123.123.123.222"<<endl;
	//		cin>>ip;
	//	}
	//	_delete_trie_tree(tree,0);
	//	i = i*10;
	//}

	int i;
	i = 1000000;
	s = GetTickCount();
	_Make_ip_file(i);
	e = GetTickCount();
	cout<<"data number = "<<i<<endl;
	cout<<"file write= "<<e-s<<endl;

	s = GetTickCount();
	tree = ip_data_read();
	e = GetTickCount();
	//_Trie_tree_visit(tree,0);
	cout<<"file read= "<<e-s<<endl;

	cout<<"请输入ip信息如下 123.123.123.222"<<endl;
	cin>>ip;
	while(ip != "over")
	{	
		s = GetTickCount();
		r = _Ip_binary_search(tree,ip);
		e = GetTickCount();
		cout<<"result = "<<r.second<<endl;
		cout<<"ip search = "<<e-s<<endl;
		cout<<"请输入ip信息如下 123.123.123.222"<<endl;
		cin>>ip;
	}
	_delete_trie_tree(tree,0);



	//cout<<e-s<<endl;
	system("pause");
	return 0;
}

// function: make file
void _Make_ip_file(size_t size)
{
	ofstream writer ;
	writer.open("ip.txt");
	writer.clear();
	int data ;
	string place[] = {"北京","天津","上海","重庆"} ;
	int ip[900];
	for(int i=0;i<900;i++)
		ip[i] = i+100;
	string ziduan = "";
	for(size_t i =0;i<size;i++)
	{
		ziduan ="";
		for(size_t j = 0; j<3; j++)
		{
			data = ip[rand()%900]  ;
			ziduan += String::Int_To_String(data)+".";
		}
		ziduan += String::Int_To_String(ip[rand()%900])+" "+place[rand()%4] ;

		writer<<ziduan<<"\n";
	}
	writer<<"over"<<endl;
	writer.close();
}


// function: read data
// input: a file 
// output: a trie tree point
// 功能:将file中的ip信息读到内存中建立的trie tree中,然后返回trie tree 的根;
vector<trie_node*>* ip_data_read()
{
	ifstream read;
	read.open("ip.txt");

	int * data = new int[4];

	string place;
	vector<trie_node*> * tree = new vector<trie_node*>();

	string ziduan = "";
	while(true)
	{
		ziduan ="";
		read>>ziduan>>place;
		if( ziduan == "over" )
			break;
		//cout<<ziduan<<place<<endl;

		std::pair<bool,int> r ;
		string num ;
		num = ziduan.substr(0,3);

		r = String::String_into_intNumber(num);
		if(r.first)
			data[0] = r.second ;
		num = ziduan.substr(4,3);

		r = String::String_into_intNumber(num);
		if(r.first)
			data[1] = r.second ;
		num = ziduan.substr(8,3);

		r = String::String_into_intNumber(num);
		if(r.first)
			data[2] = r.second ;
		num = ziduan.substr(12,3);

		r = String::String_into_intNumber(num);
		if(r.first)
			data[3] = r.second ;
		//cout<<data[0]<<" "<<data[1]<<" "<<data[2]<<" "<<data[3]<<" "<<place<<endl;
		insert_into_trie(tree,data,4,place);
	}
	read.close();
	return tree;
}

// function: insert keyword into trie tree
void insert_into_trie(vector<trie_node*> *tree,int *data,int length,string place)
{
	if(tree != NULL && data != NULL && length == 4 && !place.empty())
	{
		std::pair<bool,int> r ;
		vector<trie_node*> * root = tree ;
		vector<trie_leaf*> * leaf  ;

		// s
		trie_node * p ;
		trie_leaf * L ;
		int i = 0;
		while( i < 4 )
		{
			if(i < 3)
			{		
				r = binary_search(root,data[i]);
				// not find
				if( ! r.first )
				{
					p = new trie_node();

					p->key = data[i];
					if( i==2 )
					{
						p->leaf = new vector<trie_leaf*>();

					}
					else
					{
						p->child = new vector<trie_node*>();

					}
					root->insert(root->begin() + r.second,p);
					if(i == 2)
						leaf = p->leaf ;
					else root = p->child ;
				}
				else{
					if(i == 2)
						leaf = (*(root->begin()+r.second))->leaf ;
					else root =(*(root->begin()+r.second))->child ;
				}
			}
			else
			{
				r = binary_search_leaf(leaf,data[i]);
				// not find
				if( ! r.first )
				{
					L = new trie_leaf() ;

					L -> key = data[i] ;
					L -> place = place ;
					leaf->insert(leaf->begin()+r.second,L) ;
				}
			}
			i++;
		}
		// e
	}
	else
	{
		// not insert
	}
}

// function: binary_search;
// input: an array of node point and a key;
// output: if find key, return its subscript; or return its subscript that its should be;
// 功能;折半查找,若找到,返回关键字下标,否则返回其应该在的位置(方便插入关键字)
//std::pair<bool,vector<tire_node*>::iterator> binary_search(vector<trie_node*> *tree,int key)
std::pair<bool,int> binary_search(vector<trie_node*> *tree,int key)
{
	if(tree != NULL)
	{
		if(tree->size() == 0)
			return std::make_pair(false,tree->end() - tree->begin());

		vector<trie_node*>::iterator s = tree->begin(),e = tree ->end() -1 ,zhong;
		if((*s)->key > key)
			return std::make_pair(false,0);
		while(s <= e)
		{
			zhong = s + (e-s)/2;

			if( key < (*zhong)->key )
				e = zhong - 1;
			else if( key > (*zhong)->key)
				s = zhong + 1;
			else return std::make_pair(true,zhong - tree->begin());
		}
		if(key > (*zhong)->key)
			zhong++;
		return std::make_pair(false,zhong - tree->begin());
	}
	else
		return std::make_pair(false,tree->end() - tree->begin());
}

// function: binary_search;
// input: an array of node point and a key;
// output: if find key, return its subscript; or return its subscript that its should be;
// 功能;折半查找,若找到,返回关键字下标,否则返回其应该在的位置(方便插入关键字)
std::pair<bool,int> binary_search_leaf(vector<trie_leaf*> *tree,int key)
{
	if(tree != NULL)
	{
		if(tree->size() == 0)
			return std::make_pair(false,tree->end() - tree->begin());
		vector<trie_leaf*>::iterator s = tree->begin(),e = tree ->end() -1 ,zhong;
		if((*s)->key>key)
			return std::make_pair(false,0);
		while(s <= e)
		{
			zhong = s + (e-s)/2;

			if( key < (*zhong)->key )
				e = zhong - 1;
			else if( key > (*zhong)->key)
				s = zhong + 1;
			else return std::make_pair(true,zhong - tree->begin());
		}
		if(key > (*zhong)->key)
			zhong++;
		return std::make_pair(false,zhong - tree->begin());
	}
	else
		return std::make_pair(false,tree->end() - tree->begin());
}


// function: _Trie_tree_visit
// input:a trie tree' root point
// output:void
// 功能: 遍历 trie 树
void _Trie_tree_visit(vector<trie_node*> *tree,int level)
{
	if(tree != NULL)
	{
		if(level < 2)
			for(vector<trie_node*>::iterator it = tree->begin();it<tree->end();it++)
			{
				cout<<"root = "<<(*it)->key<<endl;
				_Trie_tree_visit((*it)->child,level+1);
			}
		else if(level == 2)
			for(vector<trie_node*>::iterator it = tree->begin();it<tree->end();it++)
			{
				cout<<"root = "<<(*it)->key<<endl;
				_Trie_tree_visit_leaf((*it)->leaf,level+1);
			}
	}
}


// function: _Trie_tree_visit
// input:a trie tree' root point
// output:void
// 功能: 遍历 trie 树的叶子
void _Trie_tree_visit_leaf(vector<trie_leaf*> *tree,int level)
{
	if(tree != NULL && level ==3)
	{
		for(vector<trie_leaf*>::iterator it = tree->begin();it<tree->end();it++)
		{
			cout<<"leaf = "<<(*it)->key<<" , place = "<<(*it)->place<<endl;
		}
	}
}


// function: ip binary search
// input: a trie tree and a keyword key
// output: return pair<bool,string>
// 功能:折半查找ip,返回其信息
std::pair<bool,string> _Ip_binary_search(vector<trie_node*>* tree,string key)
{
	if(tree != NULL && !key.empty())
	{
		vector<trie_node*>* root = tree ;
		vector<trie_leaf*>* leaf;
		std::pair<bool,int> r;
		int data[4] ;
		string ziduan;
		for(size_t i =0;i<4;i++)
		{
			ziduan = key.substr(i*4,3);
			data[i] = String::String_into_intNumber( ziduan ).second;
			if(i<3)
			{
				r = binary_search(root,data[i]);
				if(!r.first)
					return std::make_pair(false,"not find");
				if(i<2)
					root = (*(root->begin()+r.second))->child;
				else leaf =( *(root->begin()+r.second))->leaf;
			}
			else
			{
				r = binary_search_leaf(leaf,data[i]);
				if(!r.first)
					return std::make_pair(false,"not find");
				else return std::make_pair(true,(*(leaf->begin()+r.second))->place);
			}
		}
	}
	else
	{
		return std::make_pair(false,"not find");
	}
}


// function: delete the space we used;
// input: a trie tree root point vector point, and level
// output: void
// 功能: 释放掉我们开辟的空间,节省空间资源
void _delete_trie_tree(vector<trie_node*>* tree,int level)
{
	if(tree != NULL && level <3)
	{
		if(level == 2)
			for(vector<trie_node*>::iterator it = tree->begin();it<tree->end();it++)
			{
				((*it)->leaf)->clear();
			}
		else 
			for(vector<trie_node*>::iterator it = tree->begin();it<tree->end();it++)
			{
				_delete_trie_tree((*it)->child,level+1);
			}
			if(level == 0)
				tree->clear();
	}
	else
	{
		// over
	}
}

 

文本信息如下
ip.txt

 请点击下载区

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值