海量的中文分片語件使用
阿新 • • 發佈:2019-01-29
海量的中文分片語件(HLSSplit.dll),是用C++寫的.在java下呼叫,就要用JNI技術.
前段時間做了一個.希望和大家分享一下.關於JNI技術,網上有很多的介紹,還不太瞭解的朋友,可以去網上看看,很簡單,看看就明白.
首先在寫一個類,這個是在JAVA下的呼叫類.
public class fc ......{
public fc()......{
HLSplitInit();
}
public synchronized native byte[] seg(byte[] text);//分詞
public synchronized native void HLSplitInit();//初始化
public synchronized native void HLOpenUsrDict(byte[] fileName);//裝載使用者自定義詞典
public static void main(String[] args) ......{
fc a=new fc();
char c=0;
String str="供應止回閥"+c;
//String str = "潘岳與邱曉華指出,這次核算得出的結果雖不完整,但也足以對現實全貌有所估計。這些數字再次證明了,環境危機正在越來越嚴重地制約經濟發展";
String s=new String(a.seg(str.getBytes()));
System.out.print(s);
}
static......{
System.setProperty("java.library.path",System.getProperty("java.class.path"));
System.loadLibrary("fc");
}
}
其中的Main()函式裡面的內容,是顯示呼叫的方面,在實際的JNI中沒有作用.
char c=0;
String str="供應止回閥"+c; 這樣寫的原因是C中字串是有/0結束的.
執行JAVA fc.java ,然後執行JAVAH fc,產生fc.h標頭檔案.
下面建立用VC6.0建立一個空DLL工程,
然後向工程中新增fc.h,jni.h,HLSegFunc.h,HLPubDef.h,HLSSplit.lib
新增一個.cpp檔案,寫入下面的程式碼
#include <windows.h>
#include "jni.h"
#include "fc.h"
#include<stdio.h>
#include "HLSegFunc.h"
#include <string.h>
JNIEXPORT void JNICALL Java_fc_HLSplitInit(JNIEnv *, jobject)
{
HLSplitInit();
}
JNIEXPORT void JNICALL Java_fc_HLOpenUsrDict (JNIEnv *env, jobject b, jbyteArray c)
{
jbyte * arrayBody = (env)->GetByteArrayElements(c,0);
char * ptr = (char *)arrayBody;
HLOpenUsrDict(ptr);
}
JNIEXPORT jbyteArray JNICALL Java_fc_seg (JNIEnv *env, jobject b, jbyteArray c)
{
jbyte * arrayBody = (env)->GetByteArrayElements(c,0);
char * ptr = (char *)arrayBody;
HANDLE h=HLOpenSplit();
HLSplitWord(h ,ptr,HL_CAL_OPT_SEARCH);
int j=HLGetWordCnt(h);
jbyteArray d=(env)->NewByteArray(strlen(ptr)+j);
int k=0;
char *sep=" ";
for(int i=0;i<j;i++)
{
SHLSegWord* pWord=HLGetWordAt(h , i);
env->SetByteArrayRegion(d,k,strlen(pWord->s_szWord),(jbyte *)pWord->s_szWord);
k+=strlen(pWord->s_szWord);
env->SetByteArrayRegion(d,k,1,(jbyte *)sep);
k+=1;
}
HLCloseSplit(h);
return d;
}
然後,編譯就可以了.
把fc.class,fc.dll,HLSSplit.dll,HLSplitWord.dat,方面一個資料夾中,執行可以看到結果了.
我寫這個,是要在Nutch,實現中文分詞,不過,我試了試,感覺有這樣的問題:因為它是基於上面文的分詞,所以,不同的時候分詞的結果不同,這樣就給我們在搜尋的時候造成了問題,比如"美白是永遠的熱門話題",這句話的分詞結果是: 美/白/是/永遠/的/熱門/話題,而如果輸入"美白"兩個字,它就不分詞了,這樣就導致我們找不到上面的這句話了.產生這樣的原因,我認為是詞典裡面沒有"美白"這個詞.所以當你把它用到搜尋引擎的分詞是,要注意這點.
網上有很多研究Nutch中加入中文分詞技術文章,我覺得多少有些問題.過些天,我把我實現的過程,給大家分享一下,看看有沒有什麼問題.
前段時間做了一個.希望和大家分享一下.關於JNI技術,網上有很多的介紹,還不太瞭解的朋友,可以去網上看看,很簡單,看看就明白.
首先在寫一個類,這個是在JAVA下的呼叫類.
public class fc ......{
public fc()......{
HLSplitInit();
}
public synchronized native byte[] seg(byte[] text);//分詞
public synchronized native void HLSplitInit();//初始化
public synchronized native void HLOpenUsrDict(byte[] fileName);//裝載使用者自定義詞典
public static void main(String[] args) ......{
fc a=new fc();
char c=0;
String str="供應止回閥"+c;
//String str = "潘岳與邱曉華指出,這次核算得出的結果雖不完整,但也足以對現實全貌有所估計。這些數字再次證明了,環境危機正在越來越嚴重地制約經濟發展";
String s=new String(a.seg(str.getBytes()));
System.out.print(s);
}
static......{
System.setProperty("java.library.path",System.getProperty("java.class.path"));
System.loadLibrary("fc");
}
}
其中的Main()函式裡面的內容,是顯示呼叫的方面,在實際的JNI中沒有作用.
char c=0;
String str="供應止回閥"+c; 這樣寫的原因是C中字串是有/0結束的.
執行JAVA fc.java ,然後執行JAVAH fc,產生fc.h標頭檔案.
下面建立用VC6.0建立一個空DLL工程,
然後向工程中新增fc.h,jni.h,HLSegFunc.h,HLPubDef.h,HLSSplit.lib
新增一個.cpp檔案,寫入下面的程式碼
#include <windows.h>
#include "jni.h"
#include "fc.h"
#include<stdio.h>
#include "HLSegFunc.h"
#include <string.h>
JNIEXPORT void JNICALL Java_fc_HLSplitInit(JNIEnv *, jobject)
{
HLSplitInit();
}
JNIEXPORT void JNICALL Java_fc_HLOpenUsrDict (JNIEnv *env, jobject b, jbyteArray c)
{
jbyte * arrayBody = (env)->GetByteArrayElements(c,0);
char * ptr = (char *)arrayBody;
HLOpenUsrDict(ptr);
}
JNIEXPORT jbyteArray JNICALL Java_fc_seg (JNIEnv *env, jobject b, jbyteArray c)
{
jbyte * arrayBody = (env)->GetByteArrayElements(c,0);
char * ptr = (char *)arrayBody;
HANDLE h=HLOpenSplit();
HLSplitWord(h ,ptr,HL_CAL_OPT_SEARCH);
int j=HLGetWordCnt(h);
jbyteArray d=(env)->NewByteArray(strlen(ptr)+j);
int k=0;
char *sep=" ";
for(int i=0;i<j;i++)
{
SHLSegWord* pWord=HLGetWordAt(h , i);
env->SetByteArrayRegion(d,k,strlen(pWord->s_szWord),(jbyte *)pWord->s_szWord);
k+=strlen(pWord->s_szWord);
env->SetByteArrayRegion(d,k,1,(jbyte *)sep);
k+=1;
}
HLCloseSplit(h);
return d;
}
然後,編譯就可以了.
把fc.class,fc.dll,HLSSplit.dll,HLSplitWord.dat,方面一個資料夾中,執行可以看到結果了.
我寫這個,是要在Nutch,實現中文分詞,不過,我試了試,感覺有這樣的問題:因為它是基於上面文的分詞,所以,不同的時候分詞的結果不同,這樣就給我們在搜尋的時候造成了問題,比如"美白是永遠的熱門話題",這句話的分詞結果是: 美/白/是/永遠/的/熱門/話題,而如果輸入"美白"兩個字,它就不分詞了,這樣就導致我們找不到上面的這句話了.產生這樣的原因,我認為是詞典裡面沒有"美白"這個詞.所以當你把它用到搜尋引擎的分詞是,要注意這點.
網上有很多研究Nutch中加入中文分詞技術文章,我覺得多少有些問題.過些天,我把我實現的過程,給大家分享一下,看看有沒有什麼問題.