auto arrayHash = [fn = hash<int>{}] (const array<int, 26>& arr) -> size_t { return accumulate(arr.begin(), arr.end(), 0u, [&](size_t acc, int num) { return (acc << 1) ^ fn(num); }); }; 用了什么语法知识
时间: 2023-06-15 07:07:40 浏览: 430
这段代码使用了 C++11 引入的 Lambda 表达式和 C++14 引入的泛型 lambda 表达式的特性。
Lambda 表达式是一种匿名函数,它可以在需要函数对象的任何地方使用。此处使用的 Lambda 表达式定义了一个名为 `arrayHash` 的函数对象,它接受一个 `array<int, 26>` 类型的数组作为参数,并返回一个 `size_t` 类型的哈希值。Lambda 表达式中的 `[fn = hash<int>{}]` 表示定义了一个名为 `fn` 的变量,并将其初始化为 `hash<int>{}`,即一个 `int` 类型的哈希函数对象。`fn` 变量的类型由编译器推导得出。
泛型 lambda 表达式是 C++14 引入的一种新特性,它可以让 Lambda 表达式的参数具有自动类型推导的能力。此处的泛型 lambda 表达式中的 `acc` 和 `num` 参数没有指定类型,而是由编译器根据传入的实参类型自动推导得出。`accumulate` 函数中的第三个参数 `0u` 指定了初始值的类型为 `unsigned int`,这样就可以保证结果类型与 `size_t` 类型一致。Lambda 表达式中的 `&` 表示捕获外部作用域的所有变量,并使用引用方式传递。Lambda 表达式中的 `(acc << 1) ^ fn(num)` 表示将 `acc` 左移一位并异或上 `fn(num)` 的结果,从而实现了累计哈希值的功能。
相关问题
unordered_set<vector<int>>set为什么这段代码会错误
这段代码会出错是因为`vector<int>`不是一个可哈希的类型,而`unordered_set`底层是通过哈希表实现的,需要元素类型能够被哈希。如果一定要使用`vector<int>`作为`unordered_set`的元素类型,需要自定义哈希函数并提供给`unordered_set`使用。以下是一个示例的自定义哈希函数:
```c++
struct VectorHash {
size_t operator()(const std::vector<int>& v) const {
std::hash<int> hasher;
size_t seed = 0;
for (int i : v) {
seed ^= hasher(i) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
return seed;
}
};
```
然后可以这样定义`unordered_set`:
```c++
unordered_set<vector<int>, VectorHash> my_set;
```
这样就可以通过编译了。
#include<bits/stdc++.h> using namespace std; unsigned int getBlkno(string &input_data,int idx){ string s = input_data.substr(idx*4,4); unsigned int res = 0; for(int i=0;i<4;i++){ res += s[i]<<(24-i*8); } return res; } unsigned int Murmurhash3(string input_data,unsigned int seed){ unsigned int h = seed; //声明常量 const unsigned int c1 = 0xcc9e2d51; // 3,432,918,353 const unsigned int c2 = 0x1b873593; // 461,845,907 const int r1 = 15; const int r2 = 13; const int m = 5; const int n = 0xe6546b64; //3,864,292,196 //分块处理 int blkNums = input_data.size()/4; //1.一个块一个块地处理,这是第一部分地工作 for(int i=0;i<blkNums;i++){ unsigned int K = getBlkno(input_data,i); K *= c1; K = _rotl(K,r1); K *= c2; K = _rotl(K,r2); h = h*m + n; } //2.处理剩余量 string remaining_bytes = input_data.substr(blkNums*4); unsigned int k = 0; switch (remaining_bytes.size()){ case 3:k^=remaining_bytes[2]<<16; case 2:k^=remaining_bytes[1]<<8; case 1:k^=remaining_bytes[0]; } k = k * c1; k = _rotl(k,r1); k = k * c2; h ^= k; h ^= input_data.size(); //3.加强雪崩测试 h ^= h >> 16; h *= 0x85ebca6b; // 2,246,822,507 h ^= h >> 13; h *= 0xc2b2ae35; // 3,266,489,909 h ^= h >> 16; return h; } int main(){ string input_data = "Jack"; int seed = 123; cout<<"Murmurhash3(Jack,123) = "<<Murmurhash3(input_data,seed); system("pause"); }
这段代码实现了 MurmurHash3 哈希算法的计算过程。MurmurHash3 是一种高性能的非加密哈希算法,具有较高的散列质量和较低的冲突率。它将输入数据分成若干块进行处理,每块按照特定的方式进行计算,并最终得到哈希值。这段代码中的 getBlkno 函数用于获取输入数据中的一个块,并转换成无符号整数。Murmurhash3 函数则是整个哈希算法的主要实现,其中包括了分块处理、剩余量处理、雪崩测试等步骤。最后,程序将输入数据 "Jack" 和种子值 123 作为参数传递给 Murmurhash3 函数,并输出哈希值。
阅读全文