DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: melqui
今日帖子: 3
在线用户: 4
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/19 12:12:21
标题:
求各位DELPHI高手出马,封装一个结巴分词的DLL 浏览:6769
加入我的收藏
楼主: 这里有C语言的结巴分词 https://github.com/yanyiwu/cjieba ,小白多次尝试封装失败,求高手出马。
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2018/1/19 16:35:30
1楼: 话说,人家这个东西不是挺小巧的么?
有那么麻烦么?

用vc2017打的包,
有改动需求的话就自己改一下就可以了。
此帖子包含附件:bahamut8348_2018119163522.rar 大小:3.77M
----------------------------------------------
--
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2018/1/19 16:37:35
2楼: 这里是导出函数。
没有改约定的,默认统统都是cdcel
此帖子包含附件:
PNG 图像
大小:35.5K
----------------------------------------------
--
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/19 17:31:58
3楼: 感谢楼上,我试试。我用vs2017打包失败,然后用GCC,打出来的不能用,只要是对C++不太懂
----------------------------------------------
-
作者:
男 letianwuji (大器晚成) ▲▲▲▲▲ -
普通会员
2018/1/19 17:36:06
3楼: ICTCLAS50.dll 或NLPIR.dl 用下就OK的拉。
----------------------------------------------
相信自己,若自己都不相信,那还有谁可信。
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/19 17:46:07
4楼: @letianwuji 你说的这个有1个月授权限制呢,而且貌似经常不更新授权
----------------------------------------------
-
作者:
男 letianwuji (大器晚成) ▲▲▲▲▲ -
普通会员
2018/1/19 19:49:24
5楼: @badwood csdn上面有破解版,不需要授权key的dll,我发布的。
ICTCLAS50.dll 或NLPIR.dl这两个都有。
----------------------------------------------
相信自己,若自己都不相信,那还有谁可信。
作者:
男 letianwuji (大器晚成) ▲▲▲▲▲ -
普通会员
2018/1/19 22:00:32
6楼: http://download.csdn.net/download/letianwuji/7184937
http://download.csdn.net/download/letianwuji/9430904
----------------------------------------------
相信自己,若自己都不相信,那还有谁可信。
作者:
男 momo08 (默默) ▲▲▲△△ -
普通会员
2018/1/19 22:14:35
7楼: 10220f24e0925509c5fa45ea3495fd35
----------------------------------------------
-
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/20 11:15:59
8楼: @letianwuji 感谢分享,我下载了
----------------------------------------------
-
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/20 12:57:38
9楼: @letianwuji 能提供一下可用的接口PAS吗,sample/win32下的那个是自动导出的不能用呢。
----------------------------------------------
-
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/20 14:31:18
10楼: 改了一个NLPIR.pas,正在测试
此帖子包含附件:badwood_2018120143118.rar 大小:1,962B
----------------------------------------------
-
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/20 15:43:11
11楼: 请教,这一段C代码,改成pascal应该怎么写

typedef struct {
  const char* word;
  size_t len;
} CJiebaWord;

  CJiebaWord* words = Cut(handle, s, len); 
  CJiebaWord* x;
  for (x = words; x && x->word; x++) {
    printf("%*.*s\n", x->len, x->len, x->word);
  }
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2018/1/20 18:17:13
12楼: type
  pjiebaword = ^tjiebaword;
  tjiebaword = record
    word: lpcstr;
{$ifdef cpux64}
    len: uint64;
{$else}
    len: uint;
{$endif}
  end;


var
  p, pwords: pjiebaword;
begin
  pwords := cut(handle, s, len);
  p := pwords;
  while (nil != p) and (nil != p^.word) do
  begin
    showmessage(p^.word);
    inc(p);
  end;
end;
----------------------------------------------
--
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/20 19:06:53
13楼: 弱弱问一句,这里为什么不直接用pwords而要赋值给p?
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2018/1/20 20:30:51
14楼: pwords是通过函数分配出来的内存入口指针,也就是数组的入口地址。
而p是用来遍历数组元素用的。如果不通过另一个变量来遍历数组的话,那分配出来的数组入口地址就丢失了,那么这段内存就无法回收了。
----------------------------------------------
--
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/20 20:39:42
15楼: 受教了
----------------------------------------------
-
作者:
男 edwinyeah (Edwin) ★☆☆☆☆ -
盒子活跃会员
2018/1/20 23:32:08
16楼: 楼主,做成后分享出来哦 :)
----------------------------------------------
-
作者:
男 letianwuji (大器晚成) ▲▲▲▲▲ -
普通会员
2018/1/21 8:17:10
17楼: 用c的.h文件,转换成pas文件就好的,有工具的。
C2PascalhConver
----------------------------------------------
相信自己,若自己都不相信,那还有谁可信。
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/21 11:48:13
18楼: 关于12楼的代码
  while (nil != p) and (nil != p^.word) do
  begin
    showmessage(p^.word);
    inc(p);
  end;

以文本‘南京市长江大桥’为例,输出的结果是

南京市长江大桥

京市长江大桥

市长江大桥

长江大桥

江大桥

大桥


==========

这是哪里不对?
----------------------------------------------
-
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/21 12:03:53
19楼: 这是我做的结巴的接口。
此帖子包含附件:badwood_201812112103.rar 大小:3.56M
----------------------------------------------
-
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/21 12:06:40
20楼: 测试代码如下:

var
  DICT_PATH, HMM_PATH, USER_DICT, IDF_PATH, STOP_WORDS_PATH: ansistring;
  Ahandle: Thandle;
  txtlen: cardinal;
  txt: ansistring;
  pw, words: pjiebaword;
begin

  DICT_PATH := './dict/jieba.dict.utf8';
  HMM_PATH := './dict/hmm_model.utf8';
  USER_DICT := './dict/user.dict.utf8';
  IDF_PATH := './dict/idf.utf8';
  STOP_WORDS_PATH := './dict/stop_words.utf8';

  Ahandle := NewJieba(PAnsiChar(DICT_PATH), PAnsiChar(HMM_PATH), PAnsiChar(USER_DICT), PAnsiChar(IDF_PATH),
    PAnsiChar(STOP_WORDS_PATH));
  txt := '南京市长江大桥';

  txtlen := length(txt);
  words := Cut(Ahandle, PAnsiChar(txt), txtlen);

  pw := words;
  while (nil <> pw) and (nil <> pw^.word) do
  begin

    Mdest.Lines.Append(pw^.len.tostring + ' ' + pw^.word);

    inc(pw);
  end;
  FreeWords(words);
  FreeJieba(Ahandle);

==========
运行结果就是18楼那样,如果用pw^.len来判断输出,则例句被分解为单字,没有Cjiega源码生成的DEMO.EXE中的效果。

不得不说,cjieba的初始化函数加载真的很慢,但为什么释放也很慢,就不懂了。
----------------------------------------------
-
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/21 12:24:12
21楼: 找到原因了,输入的文本需要转为utf8编码,输出再解码,然后 循环按照pw^.len的长度自己截取字符串,和C里直接可以输出pw^.word不同。
----------------------------------------------
-
作者:
男 letianwuji (大器晚成) ▲▲▲▲▲ -
普通会员
2018/1/21 14:29:57
22楼: 抽空写个Demo
此帖子包含附件:letianwuji_2018121142957.pdf 大小:310.7K
----------------------------------------------
相信自己,若自己都不相信,那还有谁可信。
作者:
男 edwinyeah (Edwin) ★☆☆☆☆ -
盒子活跃会员
2018/1/21 16:48:34
23楼: @badwood, 
非常感谢分享!
关于“找到原因了,输入的文本需要转为utf8编码,输出再解码,然后 循环按照pw^.len的长度自己截取字符串,和C里直接可以输出pw^.word不同。”,可以给一段演示代码吗?谢谢。

@letianwuji,
.pdf文件?
----------------------------------------------
-
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/21 17:25:02
24楼: 演示如下:
var
  DICT_PATH, HMM_PATH, USER_DICT, IDF_PATH, STOP_WORDS_PATH: ansistring;
  Ahandle: Thandle;
  txtlen: cardinal;
  txt,newtxt: ansistring;
  pw, words: pjiebaword;
  tag: RawByteString;
begin

  DICT_PATH := './jiebadict/jieba.dict.utf8';
  HMM_PATH := './jiebadict/hmm_model.utf8';
  USER_DICT := './jiebadict/user.dict.utf8';
  IDF_PATH := './jiebadict/idf.utf8';
  STOP_WORDS_PATH := './jiebadict/stop_words.utf8';

  Ahandle := NewJieba(PAnsiChar(DICT_PATH), PAnsiChar(HMM_PATH), PAnsiChar(USER_DICT), PAnsiChar(IDF_PATH),
    PAnsiChar(STOP_WORDS_PATH));
  txt := trim(Msource.Text);
  txt := utf8encode(txt);
  txtlen := length(txt);
  words := Cut(Ahandle, PAnsiChar(txt), txtlen);
  newtxt := '';
  pw := words;
  while (nil <> pw) and (nil <> pw^.word) do
  begin
    tag := UTF8Decode(leftstr(pw^.word, pw^.len));
    newtxt := newtxt + tag + '/';

    inc(pw);
  end;
  Mdest.Lines.Append(newtxt);

  FreeWords(words);
  FreeJieba(Ahandle);
----------------------------------------------
-
作者:
男 edwinyeah (Edwin) ★☆☆☆☆ -
盒子活跃会员
2018/1/21 17:52:06
25楼: @badwood,

多谢!成功了,效果如下:
我/是/拖拉机/学院/手扶拖拉机/专业/的/。/不用/多久/,/我/就/会/升职/加薪/,/当上/CEO/,/走上/人生/巅峰/。/
----------------------------------------------
-
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/21 17:59:59
26楼: jieba初始化很慢,而且释放也特别慢,比源码里的命令行DEMO慢了很多。不知道是哪里有问题。
NLPIR好像无法加载自定义TXT词库,只看到一个个加的函数,也没找到禁用词库的设置。
----------------------------------------------
-
作者:
男 edwinyeah (Edwin) ★☆☆☆☆ -
盒子活跃会员
2018/1/21 18:00:55
26楼: @badwood,这个dll即可以后有可能用得上,以感激您的名义,给这个论坛捐款¥100,非常微不足道,微不足道,微不足道,仅表心意。
----------------------------------------------
-
作者:
男 edwinyeah (Edwin) ★☆☆☆☆ -
盒子活跃会员
2018/1/21 18:06:07
27楼: 我不清楚官方demo的运行速度,不过这里,jieba dll库的官方例子:
https://github.com/yanyiwu/cjieba/blob/master/demo.c

里面的注释说:
// init will take a few seconds to load dicts.
也就是说,初始化(主要是载入词典)需要几秒钟的时间。我这里测试你的例子,时间差不多。
----------------------------------------------
-
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/21 18:59:48
28楼: 初始化慢可以理解,但是释放也很慢啊,你测试没有?
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2018/1/21 21:05:58
29楼: 兰州既然都编译过人家的demo了。怎么不看看人家的注释呢?
人家不是已经告诉你了在初始化的时候需要等待几秒的时间来加载词典么?

至于为什么释放慢,那也和回收内存有关,兰州可以换个内存管理器看看。
----------------------------------------------
--
作者:
男 edwinyeah (Edwin) ★☆☆☆☆ -
盒子活跃会员
2018/1/21 21:44:04
30楼: @badwood, 

FreeJieba(Ahandle)这句,我这里xe4测试执行很快的。只有初始化需要几秒。
----------------------------------------------
-
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/22 10:06:12
31楼: XE6/XE10 测试 ,FreeJieba 基本都是 13秒多,我简直懵逼了
----------------------------------------------
-
作者:
男 edwinyeah (Edwin) ★☆☆☆☆ -
盒子活跃会员
2018/1/22 12:06:31
32楼: 这么夸张?no idea...
----------------------------------------------
-
作者:
男 letianwuji (大器晚成) ▲▲▲▲▲ -
普通会员
2018/1/22 12:12:31
32楼: 我也是醉了...以ICTCLAS50_Windows_32_C 破解版为例:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TCodeType = (CODE_TYPE_UNKNOWN,CODE_TYPE_ASCII,CODE_TYPE_GB,  CODE_TYPE_UTF8,  CODE_TYPE_BIG5);

 tagICTCLAS_Result = record
   iStartPos: integer; //开始位置
   iLength: integer; //长度
   szPOS: string;//词性
   iPOS: integer; //词性ID
   iWordID : integer; //词ID
   iWordType: integer; //词语类型,用户词汇?(0-否,1-是)
   iWeight: integer;// 词语权重
 end;
 PtagICTCLAS_Result = ^tagICTCLAS_Result;

 result_t = record
   start: integer;
   length: integer;
   {$IF Defined(POS_TAGGER) }
   iPOS: integer;
   sPos: array[0..POS_SIZE - 1] of char;
   {$IFEND}
   word_ID: integer;
   word_type: integer;
   weight: integer;
 end;
 Presult_t = ^result_t; 

  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

const
  dll = 'ICTCLAS50.dll';


implementation

  function ICTCLAS_Init(pszInitDir: pchar = nil): boolean; cdecl; external dll;
  function ICTCLAS_SetPOSmap(nPOSmap: integer): boolean; cdecl; external dll;
  function ICTCLAS_ParagraphProcess(const pszText: pchar;iLength: integer;pszResult: PAnsichar;codeType :TCodeType;bEnablePOS: boolean = false): integer; cdecl; external dll;
  function ICTCLAS_nativeProcAPara(sSrc:PByteArray;eCodeType:Integer;bPOStagged:Integer): PByteArray; cdecl; external dll;
{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var nRstLen: integer;
    sSentence: pchar;
    sRst: pchar;
    eCt: TCodeType;
    nrc: pinteger;
    fc : PtagICTCLAS_Result;
    fca: Presult_t;
    nativeBytes : PByteArray;

begin
  //var RtnStream :TMemoryStream; Str :String;

  //把字符串以byte方式,写入到流,不额外复制值。
  //ReqStream.WriteBuffer(Str [1], length(Str ));

  if ICTCLAS_Init() then
  begin
     //showmessage('OK');
     ICTCLAS_SetPOSmap(2);//    (2:gb2312、GBK、gb18030)

     sSentence := pchar(memo1.Lines.Text);
     getmem(sRst, length(sSentence)*60);//开辟内存
     ICTCLAS_ParagraphProcess(sSentence,length(sSentence),sRst,CODE_TYPE_GB,False);
     showmessage(sRst);


  end
  else
    showmessage('no');
end;

end.

delphi7编译...整个包有些不小,我传FTP
----------------------------------------------
相信自己,若自己都不相信,那还有谁可信。
作者:
男 letianwuji (大器晚成) ▲▲▲▲▲ -
普通会员
2018/1/22 12:16:04
33楼: 链接: https://pan.baidu.com/s/1i7lEI4P 密码: qgmy
----------------------------------------------
相信自己,若自己都不相信,那还有谁可信。
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/22 13:07:27
34楼: @letianwuji
我用你的NLPIR.DLL 做了一个NLPIR.pas,可以用。
但目前测试导入自定义词库 NLPIR_ImportUserDict,但导入后是永久的,如果要更换自定义词库就很麻烦,貌似只能一个词一个词从库里删除,试过直接删pdat文件也不行。

另外,NLPIR_ImportKeyBlackList 导入禁用词库后如果词语和用户词库有重复,就不会生效,并且没有删除禁用词的方法…………
----------------------------------------------
-
作者:
男 letianwuji (大器晚成) ▲▲▲▲▲ -
普通会员
2018/1/23 12:46:03
35楼: 不看官方手册的,是伐。
----------------------------------------------
相信自己,若自己都不相信,那还有谁可信。
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/23 18:07:54
36楼: 看过了,并没有找到我需要的资料,只得自己测试,不得不说,那份手册写的很粗略。
----------------------------------------------
-
作者:
男 letianwuji (大器晚成) ▲▲▲▲▲ -
普通会员
2018/1/23 18:14:29
37楼: 5 .1 9 新词发现批量处理功能
注:从 2016 版本开始,该功能独立为关键词抽取组件,对应函数为: NWF_Batch_Start,
NWF_Batch_AddFile, NWF_Batch_AddMem, NWF_Batch_Complete, NWF_Batch_GetResult,
NWF_Result2UserDict() 请 访 问 :
https://github.com/NLPIR-team/NLPIR/tree/master/NLPIR%20SDK/NewWordFinder
----------------------------------------------
相信自己,若自己都不相信,那还有谁可信。
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/26 11:26:56
38楼: @letianwuji 
NLPIR 2016版本有一个NLPIR_CleanUserWord()的函数,可以批量删除用户自定义词库。不过你破解的DLL版本里没有这个函数。
所以如果要修改、更换用户词库,只能用NLPIR_DelUsrWord一条条删除,如果词库较大,就比较麻烦了。
----------------------------------------------
-
作者:
男 letianwuji (大器晚成) ▲▲▲▲▲ -
普通会员
2019/8/6 1:48:33
39楼: 好吧,我把最新版破解一遍...
----------------------------------------------
相信自己,若自己都不相信,那还有谁可信。
作者:
男 lzhg_kn (lzhg_kn) ★☆☆☆☆ -
盒子活跃会员
2019/8/8 14:30:59
40楼: 好贴,别沉了
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行134.7656毫秒 RSS