今天在做题时候,把unordered_map的键值设定为自定义的结构体,发生了一系列报错。
具体代码如下:
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
#define MOD 1000000007
struct sum_sz
{
sum_sz(int sum, int sz)
:p(sum, sz)
{}
bool operator==(const sum_sz& s2)
{
return p.first == s2.p.first && p.second == s2.p.second;
}
pair<int, int> p;
};
int gethow(unordered_map<sum_sz, int>& m, int sum, int sz)
{
if (sum < sz)
return 0;
if (sum == sz || sz == 1)
return 1;
if (m.count({ sum,sz }))
return m[{sum, sz}];
int res = 0;
for (int begin = sum - sz + 1; begin > 0; begin--)
{
res += gethow(m, sum - begin, sz - 1);
res %= MOD;
}
m[{sum, sz}] = res;
return res;
}
int main() {
//return sum_sz({ 1,1 }) == sum_sz({ 2,1 });
unordered_map<sum_sz, int> m;
int n;
cin >> n;
vector<int> v(n);
int sum = 0;
for (int i = 0; i < n; i++)
{
cin >> v[i];
sum += v[i];
}
int res = gethow(m, sum, n);
for (int i = 0; i < n; i++)
res -= m[{sum - v[i], n - 1}];
res += n - 1;
cout << res << endl;
}
错误信息为:
之前只知道自定义结构体作为键值时要重载相等函数,可还是报错。
后来上网查找资料发现,unordered_map不仅要重载==,还要重载一个能映射其地址的函数。想来也是,因为底层是哈希表,要给个仿函数也不过分。
struct hash_point
{
size_t operator()(const sum_sz& ss) const {
return hash<int>()(ss.p.first) ^ hash<int>()(ss.p.second);
}
};
将这个仿函数作为第三个参数传入unordered_map的模版。
unordered_map<sum_sz, int, hash_point> m;
此外还要注意operator==应该是const的,不然也会报错。
最后的整体可运行代码如下
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
#define MOD 1000000007
struct sum_sz
{
sum_sz(int sum, int sz)
:p(sum, sz)
{}
bool operator==(const sum_sz& s2) const
{
return p.first == s2.p.first && p.second == s2.p.second;
}
pair<int, int> p;
};
struct hash_point
{
size_t operator()(const sum_sz& ss) const {
return hash<int>()(ss.p.first) ^ hash<int>()(ss.p.second);
}
};
int gethow(unordered_map<sum_sz, int,hash_point>& m, int sum, int sz)
{
if (sum < sz)
return 0;
if (sum == sz || sz == 1)
return 1;
if (m.count({ sum,sz }))
return m[{sum, sz}];
int res = 0;
for (int begin = sum - sz + 1; begin > 0; begin--)
{
res += gethow(m, sum - begin, sz - 1);
res %= MOD;
}
m[{sum, sz}] = res;
return res;
}
int main() {
//return sum_sz({ 1,1 }) == sum_sz({ 2,1 });
unordered_map<sum_sz, int, hash_point> m;
int n;
cin >> n;
vector<int> v(n);
int sum = 0;
for (int i = 0; i < n; i++)
{
cin >> v[i];
sum += v[i];
}
int res = gethow(m, sum, n);
for (int i = 0; i < n; i++)
res -= m[{sum - v[i], n - 1}];
res += n - 1;
cout << res << endl;
}
map同理,但只需要重载<,因为底层是红黑树无需映射地址,注意这个也需要是const函数。