Chinaunix

标题: [分词] C版简易中文分词服务程序(cscwsd)0.0.1发布下载 [打印本页]

作者: hightman    时间: 2006-05-28 12:57
标题: [分词] C版简易中文分词服务程序(cscwsd)0.0.1发布下载
下载站点 http://cws.twomice.net/ 同时更新

cscwsd 是英文全称 C-Simpled Chinese Word Segment Daemon 的首字缩写, 这是用标准纯 C 编写, 并配合使用 autoconf GNU软件工具包, 基本上可以很方便在的各类 Unix-Like OS 系统下顺利编译执行. 目前测试过的有 RedHat Linux (as3,as4)  FreeBSD 4.10, 5.4 ..目前只支持  GBK 编码

BTW: 用 autoconf 开发包编译出来的可执行文件约为 60~80K 视操作系统而定, 比较大, 我在 Linux 底下自己编制了一个小的 makefile 在 src/makefile.test  util/makefile.test , 编译结果是 20KB 左右, 有兴趣的可以试试
(无需 configure, 进入 util/ 目录 make -f makefile.test; 进行 src 目录 make -f makefiel.test ,然后使用 src/cscwsd 即可)

这个小程序的基本工作方式如下, 运行后在本地绑定一个端口 (缺省是 4700) 监听处理分词服务, 基本上无别的功能, 只针对输入的文字原样进行分词后然后原样输出, 注意每次输入均以 "\n" 作为处理标记, 即一行处理一次并返回.

这样作的目的在于提高分词的效率, 由专门的一支程序来处理, 别的程序只需通过 socket 与其对话即可, 客户端用什么语言都方便的实现,发布包中附带了一个 misc/CWS_test.web.php , 可以在 web 上测试分词..  速度比原 PHP直接分词要提高数十倍

而词典采用的是 .txt 格式, 解决了编辑困扰问题, 格式非常简单, 一行一条目, 词与频率之间用(TAB制表符或空格)分开

具体的程序运行说明, 请参看发布包中的 README

下载地址:  http://cws.twomice.net/cscwsd-0.0.1.tar.gz   在线测试: http://cws.twomice.net/by_server.php

安装方法:

tar xvzf cscwsd-0.0.1.tar.gz
cd cscwsd-0.0.1
./configure --prefix=/usr/local
make
make install

这样缺省就会把 cscwsd 安装到 /usr/local/sbin/ 中, 而词典 dict.txt 会安装到 /usr/local/etc 中, 请运行:

cscwsd -h  查看帮助说明

快速测试

./cscwsd -D -L /tmp/test.log

服务程序会切入后台服务, 所有的日志记录在 test.log 中, 你可以在本机 telnet localhost 4700

输入一句话试试分词效果, 类似的如下:

[hightman@sata cscwsd]$ telnet localhost 4700
Trying 127.0.0.1...
Connected to sata.sunbo.com (127.0.0.1).
Escape character is '^]'.
我是中国人
我是 中国人
/bye

[ 本帖最后由 hightman 于 2007-1-11 10:17 编辑 ]
作者: hightman    时间: 2006-05-28 12:58
呵呵, 第一次用 autoconf 工具包作东西, 请多提意见, 谢谢

http://scws.tguanlim.com/_csource/  这里是用 doxygen 生成的一份源码浏览,有兴趣人士可以参看
作者: susesuse    时间: 2006-05-28 15:24
顶,不错,支持一个!
作者: ballbb    时间: 2008-07-06 13:39
看了楼主的代码,有一个算法的问题不太明白:

static int _xtree_hasher(xtree_t xt, const char *s, int len)
{
        unsigned int h = xt->base;
        while (len--)
        {
                h += (h<<5);
                h ^= (unsigned char) s[len];
                h &= 0x7fffffff;
        }
        return (h % xt->prime);
}


这个函数中的算法是什么原理阿?我是C新手,很多东西都不懂,请楼主多多指点。
作者: zx_wing    时间: 2008-07-06 13:50
有意思。
LZ介绍一下你用的规则呢?
就是以什么样的规则去分词的,这些规则存放在什么地方,如何匹配的
作者: heixia108    时间: 2008-07-06 18:14
ding 一下
作者: ballbb    时间: 2008-07-07 00:11
下载了楼主的代码 ,有些看不懂的地方 ,想请教楼主和这里的各位大大一下 ,我是C新手 ,请多多指点

前几次错误的发到了PHP版 ,现在转到这里来 :

看了楼主的代码,有一个算法的问题不太明白:

static int _xtree_hasher(xtree_t xt, const char *s, int len)
{
        unsigned int h = xt->base;
        while (len--)
        {
                h += (h<<5);
                h ^= (unsigned char) s[len];
                h &= 0x7fffffff;
        }
        return (h % xt->prime);
}


这个函数中的算法是什么原理阿?我是C新手,很多东西都不懂,请楼主多多指点。







我的理解是:

static int _xtree_hasher(xtree_t xt, const char *s, int len)
{
        unsigned int h = xt->base;
        while (len--)  /*对于string中的每一个字符 */
        {
                h += (h<<5);       /*  h *=  33 */
                h ^= (unsigned char) s[len];     /*对于h的后八位进行^操作, 但不影响前24位*/
                h &= 0x7fffffff;   /*这一步不知道是干什么的了,但为什么取0x7fffffff这个数,而不是其他,如0x8fffffff 呢*/
        }
        return (h % xt->prime);
}






再请教 楼主 一个 问题 ,在 文件 xtree.c 中 ,

void xtree_optimize(xtree_t xt)
{
        int i, cnt;
        node_t *nodes;

        if (!xt)
                return;      

        for (i = 0; i < xt->prime; i++)
        {
                cnt = 0;
                _xtree_count_nodes(xt->trees, &cnt);
                if (cnt > 2)                       
                {
                        nodes = (node_t *)malloc(sizeof(node_t) * cnt);
                        cnt = 0;
                        _xtree_load_nodes(xt->trees, nodes, &cnt);
                        qsort(nodes, cnt, sizeof(node_t), _xtree_node_cmp);
                        _xtree_reset_nodes(nodes, 0, cnt - 1, &xt->trees);
                        free(nodes);
                }
        }
}

我觉得使用qsort似乎破坏了二叉树的结构,如果 是 最小 的 一个node排在最前面的话,那么整个二叉树便消失了,因为它的left_node 和 right_node 都是 NULL

不知道我的理解对不对





谢谢
作者: prolj    时间: 2008-07-07 02:34
中文搜索?
作者: redor    时间: 2008-07-07 14:32
原帖由 hightman 于 2006-5-28 12:57 发表
下载站点 http://cws.twomice.net/ 同时更新

cscwsd 是英文全称 C-Simpled Chinese Word Segment Daemon 的首字缩写, 这是用标准纯 C 编写, 并配合使用 autoconf GNU软件工具包, 基本上可以很方便在的各类 U ...



这个好像很久以前就看过,为啥现在猜出0.0.1版本呢?我记得以前不开源的对吧?

没看代码...冒昧问是不是用hash做词匹配?如果是的话建议你改成trie,hash用来做词匹配效率真的太低了....
可以建议你研究DOUBLE ARRAY 这玩意我没研究透,听说不错...

[ 本帖最后由 redor 于 2008-7-7 14:33 编辑 ]
作者: ballbb    时间: 2008-07-07 16:16
借问楼上,trie是什么东东啊?很快吗?
作者: prolj    时间: 2008-07-07 17:40
原帖由 ballbb 于 2008-7-7 16:16 发表
借问楼上,trie是什么东东啊?很快吗?

trie树,可以用于检索
作者: ballbb    时间: 2008-07-08 17:59
我是从楼主的主页  http://www.hightman.cn/ 下载的 1.0 的代码。但有些问题一直看不太明白。楼主的论坛不能注册,所以只好发在这里了。

在文件 xdb.c 中,函数xdb_create() 只把header写到了文件中。如果调用了函数xdb_create() 之后,便直接调用xdb_nput(), _xdb_hasher()函数产生的offset其实是不存在的,这样的话lseek的时候其实只是并没有seek到目标位置,而是只停在了文件的起始位置。这样的话,以后等文件填充了数据之后,再用_xdb_hasher()产生的offset就找不到了一开始放进去的东西了。

我是C新手,不知道理解的对不对。不对的地方请楼主多多包涵,谢谢。
作者: redor    时间: 2008-07-08 19:12
原帖由 ballbb 于 2008-7-7 16:16 发表
借问楼上,trie是什么东东啊?很快吗?


trie就是多叉数 ... 对于匹配一个词的话可以到最大化匹配,不需要设定词的长度,而且可以共享前缀

比如abc abcd 两个串 abc对于两个串来说是共用的. 也就是说你要匹配abcd的话是不会得到abc这个词的....
作者: ballbb    时间: 2008-07-09 13:36
发现楼上的也是大牛啊,发布了好多软件啊。

能把你的ibase中分词的部分独立出来吗?等我看明白了楼主的代码,再去研究研究你的。




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2