unordered_map尝试引用已删除的函数

今天在做题时候,把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函数。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值