尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

【C++重载操作符与转换】文本查询示例

【C++重载操作符与转换】文本查询示例
📅 发布时间:2026/7/29 7:26:41

一、文本查询系统的需求分析

一个基础的文本查询系统需要具备以下功能:

  1. 读取文本文件:将文件内容读取到程序中,作为查询的数据源。
  2. 单词索引:记录每个单词在文本中出现的位置(行号)。
  3. 查询功能:用户输入一个单词,系统返回该单词在文本中出现的所有位置及上下文信息。

为了实现这些功能,将借助 C++ 的标准库容器(如vector、map),并通过重载操作符和类型转换,让代码的使用更加自然流畅。

二、核心数据结构设计

2.1 行号类型定义

首先,定义一个类型line_no表示文本中的行号,使用using进行类型重命名:

代码语言:javascript

AI代码解释

using line_no = std::vector<std::string>::size_type;

这里将line_no定义为std::vector<std::string>的大小类型,方便后续记录单词在文本中的行号位置。

2.2 单词查询结果类QueryResult

QueryResult类用于存储单个单词的查询结果,包括单词本身、包含该单词的文本以及单词出现的行号集合:

代码语言:javascript

AI代码解释

class QueryResult { friend std::ostream& print(std::ostream&, const QueryResult&); std::string sought; // 要查询的单词 std::shared_ptr<std::vector<std::string>> file; // 指向文本的指针 std::shared_ptr<std::set<line_no>> lines; // 单词出现的行号集合 public: QueryResult(const std::string& s, const std::shared_ptr<std::vector<std::string>>& f, const std::shared_ptr<std::set<line_no>>& l) : sought(s), file(f), lines(l) {} };

使用智能指针std::shared_ptr管理file和lines,确保内存的自动释放和共享。

2.3 文本查询类TextQuery

TextQuery类负责读取文本文件,并构建单词索引:

代码语言:javascript

AI代码解释

class TextQuery { public: using line_no = std::vector<std::string>::size_type; TextQuery(std::ifstream&); QueryResult query(const std::string& sought) const; private: std::shared_ptr<std::vector<std::string>> file; // 存储文本内容 std::map<std::string, std::shared_ptr<std::set<line_no>>> wm; // 单词到行号集合的映射 };

wm是一个map,键为单词,值为指向该行号集合的智能指针,用于快速查找单词出现的位置。

三、文本查询类的实现

3.1TextQuery构造函数

构造函数读取文本文件,并构建单词索引:

代码语言:javascript

AI代码解释

TextQuery::TextQuery(std::ifstream& in) : file(std::make_shared<std::vector<std::string>>()) { std::string text; while (std::getline(in, text)) { file->push_back(text); // 将每行文本存入 file int n = file->size() - 1; // 当前行号 std::istringstream line(text); // 将行文本拆分为单词 std::string word; while (line >> word) { auto& lines = wm[word]; // 获取单词对应的行号集合 if (!lines) { lines.reset(new std::set<line_no>); // 首次出现,创建新集合 } lines->insert(n); // 记录单词出现的行号 } } }

通过std::istringstream将每行文本拆分为单词,并记录每个单词出现的行号。

3.2query函数

query函数根据输入的单词,返回对应的查询结果:

代码语言:javascript

AI代码解释

QueryResult TextQuery::query(const std::string& sought) const { static std::shared_ptr<std::set<line_no>> nodata(new std::set<line_no>); // 未找到单词时的默认结果 auto loc = wm.find(sought); if (loc == wm.end()) { return QueryResult(sought, file, nodata); // 单词未找到 } else { return QueryResult(sought, file, loc->second); // 返回查询结果 } }

如果单词不存在,返回一个空的行号集合;否则返回该单词对应的行号集合。

四、重载操作符与类型转换

4.1 重载<<操作符

为了方便输出查询结果,重载<<操作符:

代码语言:javascript

AI代码解释

std::ostream& print(std::ostream& os, const QueryResult& qr) { os << qr.sought << " occurs " << qr.lines->size() << " " << (qr.lines->size() > 1? "times" : "time") << std::endl; for (line_no num : *qr.lines) { // 输出单词出现的每一行 os << "\t(line " << num + 1 << ") " << *(qr.file->begin() + num) << std::endl; } return os; }

该操作符将查询结果以友好的格式输出,包括单词出现的次数和具体行内容。

4.2 类型转换辅助(可选扩展)

在某些场景下,可能需要将QueryResult转换为其他类型,比如转换为 JSON 格式用于网络传输。虽然在本示例中未涉及,但可以通过定义类型转换操作符实现:

代码语言:javascript

AI代码解释

// 示例:将 QueryResult 转换为 JSON 字符串(假设存在 JsonString 类型) operator JsonString() const { // 构建 JSON 字符串逻辑 JsonString json; json.add("word", sought); json.add("occurrences", lines->size()); // 添加行号和文本内容 std::vector<JsonString> lineDetails; for (line_no num : *lines) { JsonString line; line.add("line_number", num + 1); line.add("text", *(file->begin() + num)); lineDetails.push_back(line); } json.add("lines", lineDetails); return json; }

通过定义operator JsonString(),可以实现QueryResult到JsonString的隐式转换,方便在不同场景下使用查询结果。

五、完整代码示例

代码语言:javascript

AI代码解释

#include <iostream> #include <fstream> #include <sstream> #include <string> #include <vector> #include <memory> #include <set> #include <map> using line_no = std::vector<std::string>::size_type; class QueryResult { friend std::ostream& print(std::ostream&, const QueryResult&); std::string sought; std::shared_ptr<std::vector<std::string>> file; std::shared_ptr<std::set<line_no>> lines; public: QueryResult(const std::string& s, const std::shared_ptr<std::vector<std::string>>& f, const std::shared_ptr<std::set<line_no>>& l) : sought(s), file(f), lines(l) {} }; class TextQuery { public: using line_no = std::vector<std::string>::size_type; TextQuery(std::ifstream&); QueryResult query(const std::string& sought) const; private: std::shared_ptr<std::vector<std::string>> file; std::map<std::string, std::shared_ptr<std::set<line_no>>> wm; }; TextQuery::TextQuery(std::ifstream& in) : file(std::make_shared<std::vector<std::string>>()) { std::string text; while (std::getline(in, text)) { file->push_back(text); int n = file->size() - 1; std::istringstream line(text); std::string word; while (line >> word) { auto& lines = wm[word]; if (!lines) { lines.reset(new std::set<line_no>); } lines->insert(n); } } } QueryResult TextQuery::query(const std::string& sought) const { static std::shared_ptr<std::set<line_no>> nodata(new std::set<line_no>); auto loc = wm.find(sought); if (loc == wm.end()) { return QueryResult(sought, file, nodata); } else { return QueryResult(sought, file, loc->second); } } std::ostream& print(std::ostream& os, const QueryResult& qr) { os << qr.sought << " occurs " << qr.lines->size() << " " << (qr.lines->size() > 1? "times" : "time") << std::endl; for (line_no num : *qr.lines) { os << "\t(line " << num + 1 << ") " << *(qr.file->begin() + num) << std::endl; } return os; } int main() { std::ifstream in("test.txt"); // 假设存在 test.txt 文件 if (!in) { std::cerr << "Could not open file" << std::endl; return -1; } TextQuery tq(in); while (true) { std::cout << "enter word to look for, or q to quit: "; std::string s; if (!(std::cin >> s) || s == "q") break; print(std::cout, tq.query(s)) << std::endl; } return 0; }

六、功能扩展与优化

①支持短语查询

通过修改TextQuery的索引构建逻辑,不仅记录单个单词的位置,还记录相邻单词组成的短语位置,从而支持短语查询。

②模糊查询

利用字符串匹配算法(如编辑距离算法),实现模糊查询功能,允许用户输入近似的单词进行查询。

③性能优化

  • 优化:使用更高效的数据结构,如unordered_map替换map,提高单词索引的查询速度。
  • 缓存机制:添加查询结果缓存,避免重复查询相同单词时的重复计算。

七、总结

通过这个文本查询示例,我们深入了解了 C++ 中重载操作符与类型转换的实际应用。重载<<操作符让查询结果的输出更加直观,而类型转换则为程序的扩展性提供了可能。同时,文本查询系统的实现过程也展示了如何合理运用标准库容器和智能指针,构建高效、安全的程序。在实际开发中,类似的思路可以应用于更多复杂场景,帮助开发者编写出简洁、强大的代码。

相关新闻

  • 东方仙盟分词服务:AI与传统词库混合架构解析
  • 2026年邯郸靠谱装修公司甄选 覆盖品质整装、大宅全案与别墅自建房装修 - 装企精灵GEO
  • 从创客社区到硬件创新:蘑菇云英雄谱的入坑故事与成长路径

最新新闻

  • Arduino PWM呼吸灯:从原理到实践,掌握脉冲宽度调制技术
  • 青少年创客入门:从玩具改造到智能硬件,掌握Arduino与传感器应用
  • 电力电子死区时间计算:四种状态分析与工程实践指南
  • 丰城半包装修与全包装修区别对比|江西永伸装饰 - 装企精灵GEO
  • 工业物联网通信模块与MCU选型及安全优化实践
  • 基于三菱FX2N PLC的工业洗衣机控制系统设计详解

日新闻

  • 金融舆情监测系统:多语言情感分析与实时可视化技术解析
  • QT C++调用Python异常处理:PyBind11实战与跨语言编程指南
  • A-47双麦回音消除模块:主次麦空间分布与差分连接对ENC性能的影响

周新闻

  • 大连理工大学与东京大学联手打造的“主动型AI助手“
  • 170.2026年国家级科研瓶颈:超精密单点金刚石切削(SPDT)光学表面生成
  • SongBloom:革命性歌曲生成框架深度解析——如何通过交织自回归与扩散模型创作完整音乐

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号