ICTCLAS java调用接口改动(zz陈天)

由于ICTCLAS官方并没有发布DLL文件,但是发布了exe程序,和源码。根据源码重新封装了DLL,并且做了相应的改动。主要改动如下:


因为免费版没有DLL提供,所以这个DLL是在分词.exe系统的源代码上改的,接口也和中科院的文档有些不一样.因为我觉得中科院提供的接口太多,用起来比较麻烦. 全部改动如下:


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的三个接口函数
  public synchronized native boolean init(int i, int j);
  public synchronized native String paragraphProcess(String sParagraph);
  public synchronized native boolean fileProcess(String source,String target);

这三个是最重要的。


我把ICTCLAS类做成了一个单例,是因为我不知道多例并发这个DLL会出现什么问题。如下:
  public synchronized static ICTCLAS getInstance(){
    if (instance==null){
      instance = new ICTCLAS();
    }
    return instance;
  }
那么调用的时候,只需要
ICTCLAS ict = ICTCLAS.getInstance();
System.out.println(ict.paragraphProcess("巴拿马和美国都是国家地区,汉族是一个民族。"));


大家如果对ICTCLAS有兴趣,可以下载ICTCLAS的c++源码,看看,是MFC的.
ICTCLAS源码结构
Codes
│ ICTCLAS_WIN.cpp   Windows界面的程序
│ 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     Windows界面的资源

├─Utility           共用函数模块
│ ContextStat.cpp
│ ContextStat.h
│ Dictionary.cpp
│ Dictionary.h
│ Utility.h
│ Utility.cpp

├─Unknown           未登录词识别模块
│ UnknowWord.cpp
│ UnknowWord.h

├─Tag               HMM标注模块
│ 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              Windows界面的资源


(2)下边进行做实验测速度.
学习使用JNI调用ICTCLAS的接口。(如果有必要,自己可以重新封装DLL供自己使用)。
程序如下:
package com.xjt.nlp.word;

public class ICTCLAS {
  private static ICTCLAS instance=null;
  private ICTCLAS() {
//第一个参数0(词语切分),1(一级标注),2(二级标注).
//第二个参数0(北大标准),1(973标准),2(XML).
    init(0,0);
  }
  public synchronized static ICTCLAS getInstance(){
    if (instance==null){
      instance = new ICTCLAS();
    }
    return instance;
  }

  public synchronized native boolean init(int i, int j);
  public synchronized native String paragraphProcess(String sParagraph);
  public synchronized native boolean fileProcess(String source,String target);
  public static void main(String[] args) {
    ICTCLAS split1 = new ICTCLAS();
System.out.println("下边要处理的文本大小为48M");
long startTime=System.currentTimeMillis();
split1.fileProcess("c:\\1.txt","c:\\2.txt");
long  endTime=System.currentTimeMillis();
System.out.println(endTime-startTime);//时间为毫妙
  }
  static{
    System.loadLibrary("ICTCLAS");
  }
}

工作环境: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的花费,其效果是足够我们使用的.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值