下载地址
http://download.youkuaiyun.com/detail/mingspy/5737467
实现方法
libdatrie不支持中文,这让人用起来很是不爽。我做了如下更改,使其支持中文:
1. typedef uint16 TrieChar; // triedefs.h中
2. TRIE_CHAR_MAX 65535 // triedefs.h
3. 所有用到TrieChar大小的地方,加上sizeof(TrieChar)
alpha-map.c:382: trie_str = (TrieChar *) malloc (
sizeof(TrieChar)*(alpha_char_strlen (str) + 1));
darray.c:145: (syms->num_symbols - lower) *
sizeof(TrieChar));
darray.c:544: key = (TrieChar *) malloc (key_size*
sizeof(TrieChar));
darray.c:552: key = (TrieChar *) realloc (key, key_size*
sizeof(TrieChar));
fileutils.c:119: size_t size = (tclen(src)+1) *
sizeof(TrieChar);
tail.c:154: t->tails[i].suffix = (TrieChar *) malloc ((length+1)*
sizeof(TrieChar));
tail.c:237: file_write_chars (file, (char *)t->tails[i].suffix, length*sizeof(TrieChar)))
4. 实现
int16 tclen(const TrieChar * str){
const TrieChar * p = str;
while(*p != TRIE_CHAR_TERM) p++;
return p - str;
}
TrieChar * tcdup(const TrieChar * src){
size_t size = (tclen(src)+1) * sizeof(TrieChar);
TrieChar * dest = (TrieChar *)malloc(size);
memcpy(dest, src,size);
return dest;
}
5. TrieChar字符串拷贝换成
tail.c:284: tmp = tcdup (suffix);
6. TrieChar字符串长度换成
tail.c:233: length = t->tails[i].suffix ? tclen(t->tails[i].suffix): 0;
trie.c:590: full_key = (AlphaChar *) malloc ((tclen (key) + tclen (suffix) + 1)
7. 改变symobls的定义
struct _Symbols {
short num_symbols;
TrieChar symbols[
TRIE_CHAR_MAX];
};
存在问题
1. 会占用更多的空间。由于原来每个字符被映射到1~255空间内,也就是说每个节点最多占用256个字符。更改后,为了支持中文,每个节点至少应该支持所有中文的编码。目前我只粗暴的分配给每个节点65536个节点。理论上会浪费很多单元,实际上dat采用的内存策略会缓解这种浪费。多个节点有可能在同一块65535中(只要节点不含有相同的子节点)。
2. 目前有些字符串用libtrietool list的时候,无法显示。不过用query查询是可以查出来的。估计是显示时,字符转码代码有问题。暂时不处理。