C++之基于正倒排索引的Boost搜索引擎项目usuallytool部分代码及详解

C++之基于正倒排索引的Boost搜索引擎项目usuallytool部分代码及详解
这部分是通用工具部分的代码,简单来说就是这份代码里面的函数会在项目的其他多个部分里面被使用,所以我们专门创建一个部分用来存储这些代码。

1.FileUtil

这个类就是专门用来读取文件用的,这个代码从指定的文件路径读取文件内容,将读取到的内容(按行读取)追加到传入的字符串指针(out)所指向的字符串中;同时,该方法会返回一个布尔值,用于标识读取操作是否成功 —— 若文件成功打开并完成读取,返回 true;若文件打开失败(如路径错误等),则输出错误信息并返回 false。

文件以二进制输入模式打开,读取过程中不会修改原文件内容。

class FileUtil{ public: static bool ReadFile(const std::string &file_path,std::string *out) { //下面这行代码就是在打开文件,并通过ifstream定义一个对象in,用于关联特定的文件 std::ifstream in(file_path,std::ios::in | std::ios::binary); //这两边的in不是同一个东西,前面那个in用于关联特定的文件 //后面那个in是指定文件的打开方式,表示 "以输入模式打开文件"(即只读模式) if(!in.is_open())//这边判断文件是否打开,没打开就退出 { std::cout<<"open file "<<file_path<<": error"<<std::endl; return false; } //while里面要求是bool类型,然后getline的返回类型是输入流引用 //但在实际使用中能当作 bool 类型来使用,因为重载了 bool 类型转换操作符。 //简单来说就是要bool的地方C++会尝试转换成bool类型 std::string line; while(std::getline(in,line)) *out+=line;//把file_path的内容添加到out里面 //in 的只读特性限制的是 “不能写原文件”,而*out+=line并没有试图修改原文件 in.close();//关闭文件 return true; } };

2.JiebaUsutl

这边的话我们是相当于套皮,就是jieba这个非标准库里面有用来分词的函数,然后我们相当于是把那个函数的路径给拿出来,然后通过调用这几个路径里面的构造函数来初始化一个jieba的类,然后我们通过CutString来调用实例化后的jieba类里面的CutForSearcher来实现分词。

为什么我们要加static 呢?

1. 对于静态成员变量jieba

cppjieba::Jieba对象的初始化依赖词典文件,初始化成本较高,且分词功能通常只需要一个实例即可满足需求。用static修饰后,jieba成为类级别的成员,整个程序运行期间只会被初始化一次,避免了重复创建对象带来的资源消耗和冗余操作。确保所有使用JiebaUsutl类进行分词的地方,都共享同一个jieba实例,保证分词逻辑和词典数据的一致性。

2. 对于静态成员函数CutString

该函数的功能是调用jieba的分词方法,而jieba是静态成员(属于类本身),不需要依赖JiebaUsutl的具体实例即可访问。因此,CutStringstatic修饰后,可以直接通过类名(如JiebaUsutl::CutString)调用,无需先创建JiebaUsutl对象,简化了使用方式。

const char* const DICT_PATH = "test/cppjieba/dict/jieba.dict.utf8"; const char* const HMM_PATH = "test/cppjieba/dict/hmm_model.utf8"; const char* const USER_DICT_PATH = "test/cppjieba/dict/user.dict.utf8"; const char* const IDF_PATH = "test/cppjieba/dict/idf.utf8"; const char* const STOP_WORD_PATH = "test/cppjieba/dict/stop_words.utf8"; //test/cppjieba/test这个路径就是那个分词的函数所在的位置 class JiebaUsutl{//这边就是通过cpppjieba里面的分词来进行分词 private: static cppjieba::Jieba jieba; public: static void CutString(const std::string& src,std::vector<std::string>* out) { jieba.CutForSearch(src,*out);//这个CutForSearch就是cppjieba里面的函数 } }; cppjieba::Jieba JiebaUsutl::jieba(DICT_PATH,HMM_PATH,USER_DICT_PATH,IDF_PATH,STOP_WORD_PATH); //对类 JiebaUsutl 中的静态成员 jieba 进行初始化。 //传入几个词典相关的路径(DICT_PATH、HMM_PATH 等),就是调用 Jieba 的构造函数,用这些路径来初始化 JiebaUsutl 类里的静态成员 jieba。 //这样,在后续使用 JiebaUsutl::CutString 方法时,jieba 这个静态对象已经被正确初始化,可以调用其 CutForSearch 方法来进行分词操作了。

3. 总结

以下就是usuallytool部分的完整代码,基本上来说我们只要写项目那就肯定是需要一份usuallytool的。

#pragma once #include<iostream> #include<string> #include<fstream> #include<boost/algorithm/string.hpp> #include"cppjieba/Jieba.hpp" namespace ns_util{ class FileUtil{ public: static bool ReadFile(const std::string &file_path,std::string *out) { //下面这行代码就是在打开文件,并通过ifstream定义一个对象in,用于关联特定的文件 std::ifstream in(file_path,std::ios::in | std::ios::binary); //这两边的in不是同一个东西,前面那个in用于关联特定的文件 //后面那个in是指定文件的打开方式,表示 "以输入模式打开文件"(即只读模式) if(!in.is_open())//这边判断文件是否打开,没打开就退出 { std::cout<<"open file "<<file_path<<": error"<<std::endl; return false; } //while里面要求是bool类型,然后getline的返回类型是输入流引用 //但在实际使用中能当作 bool 类型来使用,因为重载了 bool 类型转换操作符。 //简单来说就是要bool的地方C++会尝试转换成bool类型 std::string line; while(std::getline(in,line)) *out+=line;//把file_path的内容添加到out里面 //in 的只读特性限制的是 “不能写原文件”,而*out+=line并没有试图修改原文件 in.close();//关闭文件 return true; } }; class StringUtil{ public: //target是要切分的目标,out是最后把结果输入到里面,sep是分隔符(\3) static void Split(const std::string& target,std::vector<std::string>* out,std::string sep) { boost::split(*out,target,boost::is_any_of(sep),boost::token_compress_on); //split这个函数就是用来对字符串做切分的 //token_compress_on表示会把连续的“\3”合并成一个 } }; const char* const DICT_PATH = "test/cppjieba/dict/jieba.dict.utf8"; const char* const HMM_PATH = "test/cppjieba/dict/hmm_model.utf8"; const char* const USER_DICT_PATH = "test/cppjieba/dict/user.dict.utf8"; const char* const IDF_PATH = "test/cppjieba/dict/idf.utf8"; const char* const STOP_WORD_PATH = "test/cppjieba/dict/stop_words.utf8"; //test/cppjieba/test这个路径就是那个分词的函数所在的位置 class JiebaUsutl{//这边就是通过cpppjieba里面的分词来进行分词 private: static cppjieba::Jieba jieba; public: static void CutString(const std::string& src,std::vector<std::string>* out) { jieba.CutForSearch(src,*out);//这个CutForSearch就是cppjieba里面的函数 } }; cppjieba::Jieba JiebaUsutl::jieba(DICT_PATH,HMM_PATH,USER_DICT_PATH,IDF_PATH,STOP_WORD_PATH); //对类 JiebaUsutl 中的静态成员 jieba 进行初始化。 //传入几个词典相关的路径(DICT_PATH、HMM_PATH 等),就是调用 Jieba 的构造函数,用这些路径来初始化 JiebaUsutl 类里的静态成员 jieba。 //这样,在后续使用 JiebaUsutl::CutString 方法时,jieba 这个静态对象已经被正确初始化,可以调用其 CutForSearch 方法来进行分词操作了。 }; 

Read more

小白入门:前端前端调用 AI 接口全流程(附具体案例)

很多前端新手在调用 AI 接口时会犯怵:不知道 “怎么怎么传参数?”“流式响应怎么处理?”“不同功能(润色 / 扩写)调用方式不一样吗?” 其实很简单!本文以 “智能文本处理工具” 为例,手把手教你从 0 到 1 调用 AI 接口,包含润色、扩写等功能,看完就能上手。 准备工作:先看懂这 3 个核心文件 在开始前,我们需要明确项目中 3 个关键文件的作用(这些文件你可能已经有了,只是不知道怎么用): * vite.config.js:配置后端接口代理,解决跨域问题 * apiClient.js:封装好的 HTTP 请求工具,帮你发请求 * aiService.js:封装好的 AI 功能函数(

By Ne0inhk
《算法闯关指南:优选算法--前缀和》--27.寻找数组的中心下标,28.除自身以外数组的乘积

《算法闯关指南:优选算法--前缀和》--27.寻找数组的中心下标,28.除自身以外数组的乘积

🔥草莓熊Lotso:个人主页 ❄️个人专栏: 《C++知识分享》《Linux 入门到实践:零基础也能懂》 ✨生活是默默的坚持,毅力是永久的享受! 🎬 博主简介: 文章目录 * 前言: * 27. 寻找数组的中心下标 * 解法(前缀和): * 算法思路: * C++算法代码: * 算法总结&&笔记展示: * 28. 除自身以外数组的乘积 * 解法(前缀和数组): * 算法思路: * C++算法代码: * 算法总结&&笔记展示: * 结语: 前言: 聚焦算法题实战,系统讲解三大核心板块:优选算法:剖析动态规划、二分法等高效策略,学会寻找“最优解”。 递归与回溯:掌握问题分解与状态回退,攻克组合、排列等难题。 贪心算法:理解“

By Ne0inhk
【优选算法必刷100题】第029-030题(前缀和):和为k的子数组,和可被k整除的子数组

【优选算法必刷100题】第029-030题(前缀和):和为k的子数组,和可被k整除的子数组

🔥个人主页:Cx330🌸 ❄️个人专栏:《C语言》《LeetCode刷题集》《数据结构-初阶》《C++知识分享》 《优选算法指南-必刷经典100题》《Linux操作系统》:从入门到入魔 🌟心向往之行必能至 🎥Cx330🌸的简介: 目录 前言: 29. 和为k的子数组 算法原理(前缀和+哈希): 前缀和解法代码(C++): 博主手记(字体还请见谅哈): 30. 和可被k整除的子数组 算法原理(前缀和+哈希): 前置知识补充: 前缀和解法代码(C++): 博主手记(字体还请见谅哈): 结尾: 前言: 聚焦算法题实战,系统讲解三大核心板块:“精准定位最优解”——优选算法,“简化逻辑表达,系统性探索与剪枝优化”——递归与回溯,“以局部最优换全局高效”——贪心算法,讲解思路与代码实现,帮助大家快速提升代码能力 前缀和专题 29.

By Ne0inhk
【数据结构与算法】单链表的综合运用:1.合并两个有序链表 2.分割链表 3.环形链表的约瑟夫问题

【数据结构与算法】单链表的综合运用:1.合并两个有序链表 2.分割链表 3.环形链表的约瑟夫问题

🔥小龙报:个人主页 🎬作者简介:C++研发,嵌入式,机器人等方向学习者 ❄️个人专栏:《C语言》《【初阶】数据结构与算法》 ✨ 永远相信美好的事情即将发生 文章目录 * 前言 * 一、合并两个有序链表 * 1.1题目 * 1.2 算法原理 * 1.3代码 * 二、分割链表 * 2.1题目 * 2.2 算法原理 * 2.3代码 * 三、环形链表的约瑟夫问题 * 3.1题目 * 3.2 算法原理 * 3.3代码 * 总结与每日励志 前言 链表是C语言数据结构的核心内容,也是算法面试的高频考点,其灵活的指针操作与逻辑构建对编程思维要求颇高。本文聚焦链表经典实操题型,从合并有序链表、分割链表到环形链表约瑟夫问题,由浅入深拆解解题思路,

By Ne0inhk