关于C++中双射映射及双向查找映射类型的技术问询
C++中双射映射及双向查找映射类型的技术问询
当然有办法实现这种双向查找的双射映射啦!C++标准库本身虽然没有直接提供开箱即用的双向map,但我们可以通过几种方式来满足你的需求——毕竟双射的核心要求是两边的元素都必须唯一,所以所有实现都要围绕这个规则来做:
手动封装双向映射类
最直接的思路是维护两个标准容器,比如std::map<T1, T2>(正向映射)和std::map<T2, T1>(反向映射),然后自己写一个包装类来同步这两个容器的操作,确保插入、删除、修改时两边的状态一致,同时检查唯一性。这里给你一个简单的封装示例:
#include <map> #include <stdexcept> #include <optional> template <typename T1, typename T2> class BiMap { private: std::map<T1, T2> forward_map_; std::map<T2, T1> reverse_map_; public: // 插入键值对,检查唯一性 void insert(const T1& key, const T2& value) { if (forward_map_.contains(key) || reverse_map_.contains(value)) { throw std::invalid_argument("键或值已存在,违反双射规则"); } forward_map_.emplace(key, value); reverse_map_.emplace(value, key); } // 通过T1键查找对应的T2值 std::optional<T2> find_by_key(const T1& key) const { auto it = forward_map_.find(key); if (it != forward_map_.end()) { return it->second; } return std::nullopt; } // 通过T2值查找对应的T1键 std::optional<T1> find_by_value(const T2& value) const { auto it = reverse_map_.find(value); if (it != reverse_map_.end()) { return it->second; } return std::nullopt; } // 按键删除 void erase_by_key(const T1& key) { auto it = forward_map_.find(key); if (it != forward_map_.end()) { reverse_map_.erase(it->second); forward_map_.erase(it); } } // 按值删除 void erase_by_value(const T2& value) { auto it = reverse_map_.find(value); if (it != reverse_map_.end()) { forward_map_.erase(it->second); reverse_map_.erase(it); } } };如果你需要更快的查找速度,也可以把
std::map换成std::unordered_map,只要T1和T2类型支持哈希(或者你能提供自定义哈希函数)。使用第三方库的现成实现
如果你不想自己造轮子,可以用Boost库中的boost::bimap——这是专门为双向双射映射设计的组件,已经封装好了所有同步逻辑,用起来和标准map一样顺手,还支持多种容器类型(比如基于set、unordered_set的视图)。简单的使用示例:
#include <boost/bimap.hpp> #include <iostream> // 定义一个int到string的双向map using IntStrBiMap = boost::bimap<int, std::string>; int main() { IntStrBiMap bm; bm.insert(IntStrBiMap::value_type(1, "one")); bm.insert(IntStrBiMap::value_type(2, "two")); // 正向查找:用int找string auto forward_it = bm.left.find(1); if (forward_it != bm.left.end()) { std::cout << "Key 1 maps to: " << forward_it->second << "\n"; } // 反向查找:用string找int auto reverse_it = bm.right.find("two"); if (reverse_it != bm.right.end()) { std::cout << "Value 'two' maps to: " << reverse_it->second << "\n"; } return 0; }注意Boost不是C++标准库的一部分,使用前需要确保你的项目已经链接了Boost库。
需要提醒的是,不管用哪种方式,一定要严格保证插入的键值对满足双射规则——也就是不能有重复的T1键,也不能有重复的T2值,否则会导致查找结果混乱,甚至程序出错。
内容来源于stack exchange
相关产品推荐
相关产品推荐

