【基础知识】使用Darts

Darts是double array的一个c++ template实现。经过企业级大规模数据实践检验,其效率远高于stl中的hash_set、hash_map等。

不过Darts是用c++ template实现的,初看起来,会被他的模版参数、以及函数参数等吓到,不知道怎么用。我这里写了个简单的小例子,来看一下它的使用。基本使用情景就是我有一个词表,将这个词表load到内存,转换成double array的形式,并来查询用户输入的字符串是否在当前词表当中。


贴代码。第一个函数,从文本文件中load词表,并据此构建双数组,再序列化到文件当中。

#include "darts.h"

#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <algorithm>

using namespace std;

void BuildDoubleAryFrmLex (void)
{
	// 1. load the lexicon and build double array

	// 1.1 load the lexicon and fill in a vector
	vector<string> LexVec;
	ifstream in ("Lex.txt");
	if (!in)
	{
		cerr << "Can not open the file of Lex.txt" << endl;
		return;
	}
	string sTmp;
	while (in >> sTmp)
		LexVec.push_back (sTmp);
	sort (LexVec.begin(), LexVec.end());	// it's necessary for darts

	// 1.2 make LexVec as a c-style string array, and make the value array
	char ** pStrAry = (char **)malloc (LexVec.size() * sizeof(char *));
	vector<string>::iterator pIter = LexVec.begin();
	int i = 0;
	while (pIter != LexVec.end())
	{
		pStrAry[i] = (char*)pIter->c_str();
		pIter++;
		i++;
	}

	// 1.3 build the double array
	Darts::DoubleArray theDoubleAry;
	theDoubleAry.build (LexVec.size(), pStrAry, 0, 0);

	// 1.4 save it
	theDoubleAry.save ("LexDoubleAry");
	
	// 1.5 clean up
	free (pStrAry);
}

说三点:

  1. 模版默认参数就是为c-style字符串准备的。所以用Darts::DoubleArray (注意加上“Darts”命名空间)来声明双数组,默认就是Darts::DoubleArray<char, unsigned char, int, unsigned int>。
  2. 在调用build函数构建双数组之前,所有字符串是要按照字符顺序排序的(在fill LexVec之后,调用sort函数),否则会出现异常
  3. 如果是想模拟hash_set的作用,build的后两个参数用“0”就行了;如果是要模拟hash_map,则,前面两个参数是描述key,后面两个是对应的val
第二个函数,load double array,并给用户查询:
void LookUpDoubleAry (void)
{
	// 2. load the double array and look up

	// 2.1 load the double array
	Darts::DoubleArray theDoubleAry;
	if (-1 == theDoubleAry.open ("LexDoubleAry"))
		return;

	// 2.2 look it up
	do 
	{
		cout << "input a word (quit for terminate this): " << endl;
		string sWord;
		cin >> sWord;
		if ("quit" == sWord)
			break;
		else
		{
			int iVal = 0;
			theDoubleAry.exactMatchSearch (sWord.c_str(), iVal);
			if (-1 == iVal)
				cout << "not in the lexicon" << endl;
			else
				cout << "bingo!" << endl;
		}
	} while (1);
	cout << "Bye" << endl;
}

int main (void)
{
	cout << "Now playing with Darts!" << endl;

	// BuildDoubleAryFrmLex ();

	LookUpDoubleAry();

	return 0;
}

这里调用的是exactMatchSearch函数,表示完全匹配。还有commonPrefixSearch,匹配公共前缀。
 
 

总结一下。可以看到,如果要用darts,必须要将现有的内容通过build函数构建双数组结构。在函数接口中,除了build函数,没有其他的函数能够增、删、改双数组的内容了。这说明这个工具适合用来存储资源,并提供访问接口。在效率上,个人经过大规模数据实践检验,darts效率远高于hash_set。


darts详细情况请参考上一篇转载的博文《Darts: Double-ARray Trie System》。


你可能感兴趣的:(【基础知识】使用Darts)