如何在C++中通过多组搜索值查找对应ID?
几种简便的C++实现方案:不用tuple哈希也能快速查找ID
完全理解你的困扰——为tuple写哈希函数确实有点繁琐,这里有几个更简单的方案,都能轻松实现findID功能:
方案1:用结构体+std::map(无需哈希,只需要比较运算符)
这种方案类型安全性最好,可读性也高,而且不用折腾哈希函数,因为std::map只需要你的键类型支持<比较即可。
首先定义一个存储四个值的结构体,然后重载operator<:
#include <map> #include <string> struct ValueGroup { char val1; char val2; char val3; char val4; // 重载小于运算符,用于std::map的排序 bool operator<(const ValueGroup& other) const { // 按顺序逐个比较成员,确保全序关系 if (val1 != other.val1) return val1 < other.val1; if (val2 != other.val2) return val2 < other.val2; if (val3 != other.val3) return val3 < other.val3; return val4 < other.val4; } }; // 全局或者类内的存储容器 std::map<ValueGroup, std::string> idMap = { {{'a', 'b', 'c', 'd'}, "Name1"}, {{'a', 'b', 'c', 'e'}, "Name2"}, {{'h', 'b', 'c', 'd'}, "Name3"}, {{'i', 'j', 'k', 'l'}, "Name4"} }; std::string findID(char val1, char val2, char val3, char val4) { auto it = idMap.find({val1, val2, val3, val4}); if (it != idMap.end()) { return it->second; } // 没找到的话返回空或者自定义默认值 return ""; }
方案2:用std::string作为键(最简单的实现)
把四个char直接拼接成一个string,string本身自带默认的哈希和比较逻辑,不管用std::map还是std::unordered_map都能直接用,代码量最少:
#include <unordered_map> #include <string> std::unordered_map<std::string, std::string> idMap = { {"abcd", "Name1"}, {"abce", "Name2"}, {"hbcd", "Name3"}, {"ijkl", "Name4"} }; std::string findID(char val1, char val2, char val3, char val4) { std::string key; key += val1; key += val2; key += val3; key += val4; auto it = idMap.find(key); if (it != idMap.end()) { return it->second; } return ""; }
这个方案的优点是零额外代码,直接用标准库类型,但要注意如果你的char可能包含空字符\0的话,string就不适用了(因为string以\0为结束标志),如果都是可打印字符或者确定无\0,这绝对是最省心的选择。
方案3:用64位整数作为键(性能最优)
因为每个char是8位,四个char加起来是32位,用uint64_t完全能装下,整数的哈希和查找效率是最高的,适合对性能要求高的场景:
#include <unordered_map> #include <cstdint> #include <string> // 把四个char打包成uint64_t,注意先转成unsigned char避免符号扩展 uint64_t makeKey(char val1, char val2, char val3, char val4) { uint64_t key = 0; key |= static_cast<uint64_t>(static_cast<unsigned char>(val1)) << 24; key |= static_cast<uint64_t>(static_cast<unsigned char>(val2)) << 16; key |= static_cast<uint64_t>(static_cast<unsigned char>(val3)) << 8; key |= static_cast<uint64_t>(static_cast<unsigned char>(val4)); return key; } std::unordered_map<uint64_t, std::string> idMap = { {makeKey('a','b','c','d'), "Name1"}, {makeKey('a','b','c','e'), "Name2"}, {makeKey('h','b','c','d'), "Name3"}, {makeKey('i','j','k','l'), "Name4"} }; std::string findID(char val1, char val2, char val3, char val4) { uint64_t key = makeKey(val1, val2, val3, val4); auto it = idMap.find(key); if (it != idMap.end()) { return it->second; } return ""; }
这里一定要把char转成unsigned char再移位,不然如果char是有符号类型,负数(比如ASCII值大于127的字符)会导致符号扩展,生成错误的键值。
方案选择建议
- 追求简单省心:选方案2(string键)
- 追求类型安全、可读性:选方案1(结构体+map)
- 追求极致性能:选方案3(整数键)
这三个方案都比为tuple写自定义哈希函数简单得多,完全能满足你的需求。
内容的提问来源于stack exchange,提问作者FreddyKay
相关产品推荐
相关产品推荐

