c++如何实现基于文件流的简单倒排索引数据库读写引擎【实战】

夏晨小哥_3114

夏晨小哥_3114

2026-03-27

620人浏览

原创

c++oding="utf-8" ?>

倒排索引序列化需分块处理,因std::map等结构无法直接用operator读写,应自定义序列化函数实现高效i/o。

c++如何实现基于文件流的简单倒排索引数据库读写引擎【实战】

用 std::ifstream 和 std::ofstream 读写倒排索引,核心是分块序列化

倒排索引本质是 std::map<:string std::vector>></:string> 这类结构,但直接用 operator 写二进制或文本都不可靠:标准容器内存布局不固定,<code>size_t 在 32/64 位系统下长度不同,且 std::string 内部指针不能直写。

必须自己控制序列化格式。最简方案是「纯文本分块」:每行一个词,后跟文档 ID 列表,用空格分隔。

  • 写入时遍历 index_map,对每个 term 调用 out
  • 读取时用 std::getline 拆行,再用 std::istringstream 分词,首 token 是 term,其余转成 size_t
  • 不推荐用 operator>> 直接读整行到 std::string 后 find_first_of(" ") —— 词本身含空格(如 "C++ template")就崩了

词典项排序和重复键合并,得在写入前做归一化

倒排索引要求词典项唯一、有序,否则读取后无法二分查找或合并。C++ 的 std::map 默认有序,但插入时若没去重,同一词多次出现会导致冗余数据甚至崩溃。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
  • 写入前必须调用 index_map[key].push_back(doc_id),而不是新建 key;用 index_map.emplace(key, std::vector<size_t>{doc_id})</size_t> 会覆盖已有项
  • 如果原始数据已含重复 doc_id(比如同一篇文档多次命中),需手动 dedup:std::sort + std::unique 或用 std::set<size_t></size_t> 中转再转回 vector
  • 注意大小写:默认 std::map 区分大小写,若需忽略,构造时传 std::less 或自定义比较器,否则 "Apple" 和 "apple" 被当两个词

std::fstream 打开模式选错,会导致写入无声失败或读取乱码

常见错误是用 std::ios::binary 写文本格式,或用 std::ios::app 追加却没清空旧文件,导致索引重复膨胀。

  • 写入用 std::ofstream out("index.txt", std::ios::out) 即可,默认覆盖;加 | std::ios::trunc 更明确
  • 读取必须用 std::ifstream in("index.txt"),不要加 binary —— Windows 下换行符 \r\n 会被当成两个字符,std::getline 可能截断
  • 打开后务必检查 if (!in.is_open() || !in.good()),否则后续读取返回空 vector 却不报错,调试时极难定位

内存映射不是必须的,小索引用普通流更稳

有人一上来就想用 mmap 或 boost::iostreams::mapped_file 提速,但对几 MB 以内的索引,反而增加复杂度和崩溃风险。

  • 10 万词以内、平均倒排链长 std::ifstream 读取耗时通常
  • 真正要上内存映射,前提是:索引 >100MB、查询频繁且只读、运行环境支持 POSIX mmap 或 Windows CreateFileMapping
  • 用 mmap 后仍要自己解析文本格式 —— 它只是把文件当内存数组暴露,不会自动帮你 split term 和 parse numbers

最易被忽略的是词边界处理:文本格式下必须确保 term 不含空格或换行,否则解析逻辑直接失效;上线前至少用含中文、连字符、点号的词(如 "c++"、"a.b")跑一遍测试。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

2025.09.05

570

5

golang map相关教程
golang map相关教程

本专题整合了golang map相关教程,阅读专题下面的文章了解更多详细内容。

2025.11.16

323

7

golang map原理
golang map原理

本专题整合了golang map相关内容,阅读专题下面的文章了解更多详细内容。

2025.11.17

513

20

java判断map相关教程
java判断map相关教程

本专题整合了java判断map相关教程,阅读专题下面的文章了解更多详细内容。

2025.11.27

283

6

数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

2023.06.29

2685

3

如何删除数据库
如何删除数据库

删除数据库是指在MySQL中完全移除一个数据库及其所包含的所有数据和结构,作用包括:1、释放存储空间;2、确保数据的安全性;3、提高数据库的整体性能,加速查询和操作的执行速度。尽管删除数据库具有一些好处,但在执行任何删除操作之前,务必谨慎操作,并备份重要的数据。删除数据库将永久性地删除所有相关数据和结构,无法回滚。

2023.08.14

3921

10

vb怎么连接数据库
vb怎么连接数据库

在VB中,连接数据库通常使用ADO(ActiveX 数据对象)或 DAO(Data Access Objects)这两个技术来实现:1、引入ADO库;2、创建ADO连接对象;3、配置连接字符串;4、打开连接;5、执行SQL语句;6、处理查询结果;7、关闭连接即可。

2023.08.31

2971

3

MySQL恢复数据库
MySQL恢复数据库

MySQL恢复数据库的方法有使用物理备份恢复、使用逻辑备份恢复、使用二进制日志恢复和使用数据库复制进行恢复等。本专题为大家提供MySQL数据库相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.05

947

5

vb中怎么连接access数据库
vb中怎么连接access数据库

vb中连接access数据库的步骤包括引用必要的命名空间、创建连接字符串、创建连接对象、打开连接、执行SQL语句和关闭连接。本专题为大家提供连接access数据库相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.09

2607

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习