首页 > 编程语言 >c++ std::hash<std::string> 字符串哈希函数

c++ std::hash<std::string> 字符串哈希函数

时间:2023-08-08 17:45:36浏览次数:46  
标签:std FNV const Val c++ Count hash First size

msvc

采用了FNV-1a的哈希算法

// 众所周知 std::string 就是一个 basic_string<char>
template <class _Elem, class _Traits, class _Alloc>
struct hash<basic_string<_Elem, _Traits, _Alloc>> {
    _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef basic_string<_Elem, _Traits, _Alloc> _ARGUMENT_TYPE_NAME;
    _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef size_t _RESULT_TYPE_NAME;

    _NODISCARD size_t operator()(const basic_string<_Elem, _Traits, _Alloc>& _Keyval) const noexcept {
        return _Hash_array_representation(_Keyval.c_str(), _Keyval.size());
    }
};

// 转换成bytes进行计算
template <class _Kty>
_NODISCARD size_t _Hash_array_representation(
    const _Kty* const _First, const size_t _Count) noexcept { // bitwise hashes the representation of an array
    static_assert(is_trivial_v<_Kty>, "Only trivial types can be directly hashed.");
    return _Fnv1a_append_bytes(
        _FNV_offset_basis, reinterpret_cast<const unsigned char*>(_First), _Count * sizeof(_Kty));
}

// 最终使用FNV-1a哈希算法
// These FNV-1a utility functions are extremely performance sensitive,
// check examples like that in VSO-653642 before making changes.
#if defined(_WIN64)
_INLINE_VAR constexpr size_t _FNV_offset_basis = 14695981039346656037ULL;
_INLINE_VAR constexpr size_t _FNV_prime        = 1099511628211ULL;
#else // defined(_WIN64)
_INLINE_VAR constexpr size_t _FNV_offset_basis = 2166136261U;
_INLINE_VAR constexpr size_t _FNV_prime        = 16777619U;
#endif // defined(_WIN64)

_NODISCARD inline size_t _Fnv1a_append_bytes(size_t _Val, const unsigned char* const _First,
    const size_t _Count) noexcept { // accumulate range [_First, _First + _Count) into partial FNV-1a hash _Val
    for (size_t _Idx = 0; _Idx < _Count; ++_Idx) {
        _Val ^= static_cast<size_t>(_First[_Idx]);
        _Val *= _FNV_prime;
    }

    return _Val;
}

参考

Which hashing algorithm is best for uniqueness and speed?

标签:std,FNV,const,Val,c++,Count,hash,First,size
From: https://www.cnblogs.com/miyanyan/p/17615009.html

相关文章

  • C++STL 学习笔记
    C++STL学习笔记STL补充List链表list<int>mylist={}链表定义和初始化voidpush_front(constT& val)将val插入链表最前面voidpop_front()删除链表最前面的元素list.push_back() 增加一个新的元素在list的尾端list.pop_back() 删除list的......
  • C++ | 运算符重载
    运算符重载在类中的函数进行重载(成员函数)运算符重载用于重新定义运算符的作用,使用函数名称operatorOP作为函数名,其中OP为具体的运算符(如operator+)classTime{Timeoperator+(constTime&t);};Timea,b;Timec=a+b;在成员函数中重载的运算符,如+-等,默认左边......
  • C++ | const的使用
    const基础用法用于声明一个不可再被修改的变量:constintnum=17;num=33; //Invalid,会报错用于指针首先,如果将一个指针用const声明为常量指针,那么这个指针的指向将不能被改变。但可以通过这个指针来修改被指向的对象:intdemo=17;int*constp=&demo; //......
  • windows下cmake C++库打包成C方式导出
    背景windows下当前的一个项目使用的编译器是mingw,想要使用一个使用msvc编译出来的C++库。方法重新创建一个库,这个使用extern"C"方式导出函数,在函数中调用msvc编译出来的库。项目文件文件结构|--CMakeLists.txt|--floor_calibration||--include|||--floor_c......
  • HashMap的一些常见面试问题
    HashMaph一些常见面试问题一、hashmap底层如何实现的?jdk1.7中通过数组+链表实现;jdk1.8中通过数组+链表+红黑树实现它的主干是数组嘛,一个table数组使用链表是为了解决哈希冲突嘛所采用的链地址法红黑树是为了避免链表过长导致的查询效率变低它的一个底层存储原理是通过哈希......
  • 大一下第二学期期中知识复习梳理 之 c++动态内存分配
    一、动态内存分配基本概念1、数组实现顺序表的缺陷:静态内存管理——程序在编译时,根据数组元素类型和个数分配所需内存大小,在程序运行时无法改变。2、内存空间分布 3、动态内存管理1) 2)动态内存分配(1)操作符new动态分配变量数组(对象数组): 指针变量=new变量类型[变量表......
  • C++类和对象_继承
    继承概述作为面向对象的三大特性之一,继承(inheritance)是面向对象编程中代码复用的一种重要手段。继承是类设计层面的一种复用,它允许在保证原有类性质不变的基础上对其进行扩展新的属性和功能,产生新的类。例如,在类person中定义关于‘人’的基本属性和行为,以person为基础扩展......
  • C++入门到放弃(10)——操作符重载:operator
    ​1.重载重载允许创建多个名称相同,但输入不同的函数,这些函数的参数列表不同,可以通过给予不同输入变量调用对应的函数。函数重载的关键是函数的参数列表。如果两个函数的参数数量和类型相同,同时参数的排列顺序也相同,那么就是同一个函数,不构成重载,它与f返回值和变量名都无关。v......
  • Windows c++检测笔记本是否处于睡眠状态
    最近遇到一个问题,程序需要检测电脑是否处于睡眠状态。一开始使用的方式是在WindowProc里监听WM_POWERBROADCAST消息,对PBT_APMSUSPEND``PBT_APMRESUMEAUTOMATIC消息做处理。但是实际测试中发现,这种方法在台式机中运行良好,但是放到笔记本电脑里就不行,系统休眠时监听不到WM_POWERBRO......
  • vc++2008通过paho c语言客户端接入MQTT
    因项目需要,IoT平台需要支持vc++2008接入。因为Paho的c++客户端不支持低版本vc++,所以不得不尝试通过c语言的库实现。类库下载从github下载c语言包。例如:eclipse-paho-mqtt-c-win32-1.3.12.ziphttps://github.com/eclipse/paho.mqtt.c/releases类库整合和配置解压出来的c语言......