由于ICTCLAS官方并没有发布DLL文件,但是发布了exe程序,和源码。根据源码重新封装了DLL,并且做了相应的改动。主要改动如下:
init函数:中科院的DLL没有参数,我提供两个参数,i=nOutputFormat, j=nOperateType,i和j的取值范围都是{0,1,2},有兴趣你可以改变一下init的方式试试看.
ICTCLAS_API bool ICTCLAS_SetOutputFormat(int nOutputFormat);
ICTCLAS_API bool ICTCLAS_SetOperType(int nOperateType);
这两个函数我把它删除掉了,因为已经在init中设置好了.
ICTCLAS_API bool ICTCLAS_SentenceProcess(char *sSentence,unsigned int nResultCount,char **sResult);
经过试验,我认为这个函数和pargraphProcess差不多,所以和paragraphProcess合并成一个函数.
ICTCLAS_API bool ICTCLAS_FileProcess(char *sSourceFilename,char *sResultFilename);
这是最不稳定的一个函数,当文件过大时容易产生错误. 这个错误并不是我造成的, 因为同一个文件试验原有系统也会出错,我没有修改这个错误,也不打算用这个函数,因为文件可以转换为段落,然后用paragraphProcess函数解析就可以,但是我仍然保留了这个函数.
exit()函数,我认为太麻烦,不是每次都记得要exit(),干掉了
改动后我经过多线程长时间并发测试,发现paragraphProcess函数是比较稳定的,做论文和学习是足够用了.
最后,再次申明, 千万不要将本代码用于商业用途.
其实这个Java包中其他的都没有什么用,最关键的部分是:ICTCLAS.java,这个文件里面定义了DLL的三个接口函数:
这三个是最重要的。
我把ICTCLAS类做成了一个单例,是因为我不知道多例并发这个DLL会出现什么问题。如下:
那么调用的时候,只需要
ICTCLAS ict = ICTCLAS.getInstance();
System.out.println(ict.paragraphProcess("巴拿马和美国都是国家地区,汉族是一个民族。"));
大家如果对ICTCLAS有兴趣,可以下载ICTCLAS的c++源码,看看,是MFC的.
ICTCLAS源码结构
Codes
│ ICTCLAS_WIN.cpp
│ ICTCLAS_Win.dsp
│ ICTCLAS_WIN.dsw
│ ICTCLAS_WIN.h
│ ICTCLAS_Win.exe
│ ICTCLAS_WinDlg.cpp
│ ICTCLAS_WinDlg.h
│ resource.h
│ StdAfx.cpp
│ StdAfx.h
│ log.txt
│ ICTCLAS_Win.rc
│
├─Utility
│ ContextStat.cpp
│ ContextStat.h
│ Dictionary.cpp
│ Dictionary.h
│ Utility.h
│ Utility.cpp
│
├─Unknown
│ UnknowWord.cpp
│ UnknowWord.h
│
├─Tag
│ Span.cpp
│ Span.h
│
├─Segment
│ DynamicArray.h
│ NShortPath.cpp
│ NShortPath.h
│ Queue.cpp
│ Queue.h
│ SegGraph.cpp
│ Segment.cpp
│ Segment.h
│ DynamicArray.cpp
│ SegGraph.h
│
├─Result
│ Result.cpp
│ Result.h
│
├─Data
│ lexical.ctx
│ BigramDict.dct
│ coreDict.dct
│ nr.dct
│ nr.ctx
│ ns.ctx
│ ns.dct
│ tr.dct
│ tr.ctx
│
└─res
(2)下边进行做实验测速度.
学习使用JNI调用ICTCLAS的接口。(如果有必要,自己可以重新封装DLL供自己使用)。
程序如下:
package com.xjt.nlp.word;
public class ICTCLAS {
//第一个参数0(词语切分),1(一级标注),2(二级标注).
//第二个参数0(北大标准),1(973标准),2(XML).
System.out.println("下边要处理的文本大小为48M");
long startTime=System.currentTimeMillis();
split1.fileProcess("c:\\1.txt","c:\\2.txt");
long
System.out.println(endTime-startTime);//时间为毫妙
}
工作环境:WinXP,赛扬1.2G,SDR256M
为了测试使用JNI调用大型文本的分词能力,我们处理一个48M的txt文本(内容是金庸的小说,譬如书剑恩仇录).经过处理后我们可以得到一个86M经过分分词的txt文本.
整个过程所花的时间为1607140ms=1607.140s=26.78m
平均处理速度1.8M/分钟.
如果不是使用JNI进行访问,而是直接使用其c++源码进行文本的分词
整个过程所花的时间为1552454ms=1552.454s=25.87m
则其平均处理速度为:1.85M/分钟
所以这么来说,使用JNI就在于时间花费在使用JNI调用dll的花费,其效果是足够我们使用的.