C++17:如何从string_view高效保存临时字符串实现翻译器类?
问题:高效保存string_view指向的字符串,实现双向翻译类
需求说明
需要实现一个Translator类,支持双语单词对的存储与双向翻译,具体要求:
- 类接口定义:
class Translator { public: void Add(string_view source, string_view target); string_view TranslateForward(string_view source) const; string_view TranslateBackward(string_view target) const; private: // 成员变量待实现 };
- 核心功能:
- 默认构造空翻译库
Add(source, target):添加源词与目标词的对应关系,传入的字符串可能先于Translator对象销毁TranslateForward(source):正向翻译,返回对应目标词;无匹配返回空;多次添加同一源词,返回最后一次的目标词TranslateBackward(target):反向翻译,逻辑同正向
- 约束:每个字符串在
Translator实例中最多存储一份,重复存储会触发内存超限错误
核心问题
传入Add的string_view可能指向临时对象,对象销毁后string_view会变成悬垂引用。如何安全、高效地保存字符串内容,让后续使用的string_view始终指向有效内存?
解决方案
核心思路是维护一个唯一字符串存储池,所有string_view都指向该池中的字符串,确保内存有效性;同时用两个映射维护双向翻译关系:
完整实现代码
#include <string> #include <string_view> #include <unordered_map> #include <unordered_set> class Translator { public: void Add(std::string_view source, std::string_view target) { // 将源词和目标词插入存储池,自动去重 const std::string* src_ptr = &*storage_.insert(std::string(source)).first; const std::string* tgt_ptr = &*storage_.insert(std::string(target)).first; // 用存储池中的字符串创建string_view,更新映射 forward_map_[std::string_view(*src_ptr)] = std::string_view(*tgt_ptr); backward_map_[std::string_view(*tgt_ptr)] = std::string_view(*src_ptr); } std::string_view TranslateForward(std::string_view source) const { auto it = forward_map_.find(source); return it != forward_map_.end() ? it->second : std::string_view{}; } std::string_view TranslateBackward(std::string_view target) const { auto it = backward_map_.find(target); return it != backward_map_.end() ? it->second : std::string_view{}; } private: // 存储所有唯一字符串,保证每个字符串仅存一份 std::unordered_set<std::string> storage_; // 正向映射:源词string_view → 目标词string_view std::unordered_map<std::string_view, std::string_view> forward_map_; // 反向映射:目标词string_view → 源词string_view std::unordered_map<std::string_view, std::string_view> backward_map_; };
关键细节说明
- 存储池的作用:
std::unordered_set<std::string>自动处理字符串去重,插入时若字符串已存在则不会重复存储,严格满足“每个字符串仅存一份”的约束。存储池中的字符串生命周期与Translator对象一致,避免悬垂引用。 - 获取有效string_view:插入存储池后,通过
insert返回的迭代器获取指向池中字符串的指针,再基于该指针创建string_view,确保后续使用的string_view始终指向有效内存。 - 映射的效率:用
string_view作为映射的键和值,无需额外拷贝字符串,保证操作的高效性;unordered_map提供O(1)平均时间复杂度的查找,符合翻译功能的性能需求。 - 覆盖逻辑:当重复添加同一源词/目标词时,
forward_map_和backward_map_会自动覆盖旧的映射关系,满足“返回最后一次结果”的要求。
内容的提问来源于stack exchange,提问作者Daniil Yefimov
相关产品推荐
相关产品推荐

