在C++中调用Jieba进行中文分词

来源:互联网 发布:男生不喜欢女生 知乎 编辑:程序博客网 时间:2024/06/11 15:03

背景

之前有个小项目用到了中文分词,但当时使用的ICTCLAS需要每个月下载证书,很不方便。后来在网上找到了一个开源的python实现的中文分词器Jieba,可以使用pip直接安装本地。但之前的项目是c++实现的,所以需要考虑跨语言的调用问题。
Python.h中提供了PyRun_SimpleString()方法,可以执行简单的python语句,但无法获取输出的数据。另外也提供了PyObject_CallObject(),可以将python命令的执行结果作为PyObject对象指针返回。

代码实现:类定义

class PyTextCut{                                     private:                                             PyObject *pName,*pModule,*pDict,*pFunc;      public:                                              PyTextCut();                                     string cut(string input); //Jieba分词的调用入口        ~PyTextCut();                                private:                                             int init();                              };                                               

代码实现:初始化

PyTextCut::PyTextCut(){       init();               }                         string PyTextCut::init(){    Py_Initialize();                                       // 检查初始化是否成功     if ( !Py_IsInitialized() ) {                                         return -1;                                           }                                                          // 添加当前路径                                                  PyRun_SimpleString("import sys");                          PyRun_SimpleString("reload(sys)");                         PyRun_SimpleString("sys.setdefaultencoding('utf8')");      // 载入jieba                                                 pName = PyString_FromString("jieba");                      pModule = PyImport_Import(pName);                          if ( !pModule ) {                                              printf("can't find jieba");                                return -1;                                             }                                                          pDict = PyModule_GetDict(pModule);                         if ( !pDict ) {                                                return -1;                                             }                                                       //查找函数cut                                                  pFunc = PyDict_GetItemString(pDict, "cut");                if ( !pFunc || !PyCallable_Check(pFunc) ) {                    printf("can't find function [cut]");                       return -1;                                             }   }                                                   

代码实现:调用分词方法

string PyTextCut::cut(string input){                                  string output = "";                                               PyObject *pArgs = PyTuple_New(1);                                 PyTuple_SetItem(pArgs, 0, Py_BuildValue("s",input.c_str()));      // 执行cut    PyObject *pRet = PyObject_CallObject(pFunc, pArgs);               //因为返回的是生成器类型的对象,所以必须用迭代器来访问    PyObject *iter = PyObject_GetIter(pRet);                          if( !iter ){                                                          printf("can't find iter");                                        return input;                                                 }                                                                 PyObject *next = NULL;                                            while(true){                                                          next = PyIter_Next(iter);                                         if( !next ){                                                          break;                                                        }                                                                 string str = PyString_AsString(next);                             output += str + " ";//将分词结果用空格隔开    }                                                                 Py_DECREF(pArgs);    Py_DECREF(pRet);                                                  Py_DECREF(iter);                                                  return output;                                                }                                                                 

代码实现:减少引用计数,释放资源

PyTextCut::~PyTextCut(){                          if(pFunc != NULL) Py_DECREF(pFunc);           if(pDict != NULL) Py_DECREF(pDict);           if(pModule != NULL) Py_DECREF(pModule);       if(pName != NULL) Py_DECREF(pName);           // 释放              Py_Finalize();                          }                                              
原创粉丝点击