我们如何为 C++ 无序集定制自己的哈希函数以获得特定的顺序?
你不能可靠地做你想做的事。
但是你为什么不使用std::set(或std::map)来达到这个目的呢?查看this C++ reference,并阅读好的C++ programming book(和C++11 标准n3337),了解更多信息。
我们不知道您的实际用例是什么,但我可能建议您创建自己的 class,遵循 C++ rule of five,并拥有两者
std::map 和 std::hash_map 表示相同数学关系。
class YourClass {
// incomplete, should follow the rule of five
private:
std::map<std::string, long> mapstr;
std::unordered_map<std::string, long> hashstr;
public:
void put(const std::string&str, long n) {
mapstr.insert({str,n});
hashstr.insert({str,n});
}
/// etc...
};
当然,如果您正在编写多线程程序,则需要在上面的类中有一些 std::mutex 字段,以使用 std::lock_guard 序列化访问......
知道如何编写自己的哈希函数吗?
编写一个足够好的哈希函数通常很容易。
编写一个非常有效的哈希函数仍然可以让你获得博士学位,并且你会在ACM 赞助的会议上找到许多关于该主题的论文。
这是一个 simple 和 naive 对字符串的哈希函数:
std::size_t naive_string_hash(const std::string&str) {
constexpr unsigned k1 = 78139; // a prime number
constexpr unsigned k2 = 98129; // another prime number
std::size_t h = 38197; // yet another prime number
for (char c: str)
h = (k1 * h) ^ (k2 * (unsigned)c);
return h;
}
您可以用+ 替换按位独占或^ 并阅读Bézout's identity。
我强烈建议寻找现有 C++ 开源代码(包括GCC 和Clang 的代码,它们都是C++ 编译器;或FLTK 或Qt) 可在 github 或 gitlab 等网站上找到。您可能需要征得您的经理的许可才能研究此类代码。
建议:阅读文档
我邀请您阅读您的 C++ 编译器(可能是 GCC 或 Clang)、您的链接器(可能是 binutils)、您的 source code editor(我喜欢 GNU emacs)、您的文档版本控制系统(例如git)。如果允许的话,我建议在你的电脑上使用 GNU/Linux 系统(例如Debian 或Ubuntu)(因为 Linux 主要是由开源组件组成的,其源代码你可以下载学习)。
另见http://linuxfromscratch.org/和https://norvig.com/21-days.html