C++ 在leetcode中设计哈希集时,代码给出运行时错误

C++ 在leetcode中设计哈希集时,代码给出运行时错误,c++,runtime-error,C++,Runtime Error,我试图解决一个关于设计哈希集的问题 在不使用任何内置哈希表库的情况下设计哈希集 具体而言,您的设计应包括以下两个功能: 添加(值):将值插入哈希集中。 contains(value):返回值是否存在于哈希集中 移除(值):移除哈希集中的值。如果该值在哈希集中不存在,请执行以下操作 没什么 例如: MyHashSet hashSet=新的MyHashSet();hashSet.add(1) hashSet.add(2);hashSet.contains(1);//返回true hashSet.co

我试图解决一个关于设计哈希集的问题

在不使用任何内置哈希表库的情况下设计哈希集

具体而言,您的设计应包括以下两个功能:

添加(值):将值插入哈希集中。
contains(value):返回值是否存在于哈希集中

移除(值):移除哈希集中的值。如果该值在哈希集中不存在,请执行以下操作 没什么

例如:

MyHashSet hashSet=新的MyHashSet();hashSet.add(1)
hashSet.add(2);hashSet.contains(1);//返回true hashSet.contains(3);//返回false(未找到)hashSet.add(2)
hashSet.contains(2);//返回真hashSet.remove(2)
hashSet.contains(2);//返回false(已删除)

注:

所有值都将在[1000000]的范围内。人数 操作将在[1,10000]的范围内。请不要使用 内置HashSet库

以下代码在本地运行良好,但在提交时失败,并给出错误

运行时错误消息: 类型“int”的未对齐地址0x736c61662c657572的引用绑定,需要4字节对齐

最后执行的输入: [“MyHashSet”、“添加”、“删除”、“添加”、“包含”、“添加”、“删除”、“添加”、“添加”、“添加”、“添加”、“添加”] []、[6]、[4]、[17]、[14]、[17]、[14]、[14]、[18]、[14]]

类MyHashSet{public:
向量集散列;
MyHashSet(){
储备(10000);
}
无效添加(整数键){
int bucket=键%10000;
向量::迭代器;
it=find(setHash[bucket].begin(),setHash[bucket].end(),key);
if(it==setHash[bucket].end()){
setHash[bucket]。推回(键);
}
}
无效删除(int键){
int bucket=键%10000;
向量::迭代器it1;
it1=find(setHash[bucket].begin(),setHash[bucket].end(),key);
if(it1!=setHash[bucket].end()){
int index=distance(it1,setHash[bucket].begin());
setHash[bucket].erase(setHash[bucket].begin()+索引);
}
}
/**如果此集合尚未包含指定的元素,则返回true*/
布尔包含(int键){
int bucket=键%10000;
向量::迭代器it2;
it2=find(setHash[bucket].begin(),setHash[bucket].end(),key);
if(it2!=setHash[bucket].end()){
返回true;
}
返回false;
}
})


我怀疑这是因为内存问题。但我还是无法理解,因为我仍然在学习C++的基本原理。

如果你的问题是如何修复你的实现,我会注意评论中的建议。 如果你想了解C++,并用最理想的方式解决问题,我会用的。事实上,他们给了你定义的输入范围[11000000],这让我相信他们正在寻找类似的东西

因此,这可能属于内置哈希表库的范畴

类MyHashSet{
公众:
无效添加(整数键){
标志。设置(键);
}
无效删除(int键){
标志。重置(键);
}
布尔包含(整型键)常量{
返回标志[键];
}
私人:
位集标志;
};
在我的平台上,这需要约16kB(而10000个向量需要30kB以上)。它也不需要动态内存分配


如果你考虑这个话题或作弊,请提供LeTeCal码问题的标题/编号,这样我就可以使用他们的测试用例来处理代码草案。我现在也在研究散列表,所以这将是一个双赢的结果。

法官似乎很友善,提供了令人震惊的输入。你应该自己编写一个简单的
main
来执行这些输入,看看会发生什么。如果您已经这样做了,请将其添加到问题中。
int index=distance(it1,setHash[bucket].begin())这看起来很奇怪。您不应该替换距离中的参数吗?
?方便阅读和编辑。阅读后,问问自己,“我使用的是正确的吗?”以下代码在本地运行良好——将
setHash[bucket]
替换为
setHash.at(bucket)
,您将看到它在本地不再运行良好。事实上,抛出的
std::out_of_range
异常将告诉您问题所在。“没有重新分配可能性的向量”并不完全正确。它所做的是在不构造元素和更新元素计数的情况下预先分配存储。然后,在超出保留容量之前,您可以使用推送和放置功能,而无需调整大小。它可以重新分配。您的程序失败,因为已分配了
setHash[bucket]
,但未包含正确构造的
向量
setHash[bucket]。请向后推(键)
会将
int
写入内存中的某个随机位置,该位置未正确对齐以处理
int
class MyHashSet { public:
vector<vector<int>> setHash;
MyHashSet() {
    setHash.reserve(10000);
}

void add(int key) {
    int bucket = key % 10000;
    vector<int>::iterator it;
    it = find(setHash[bucket].begin(),setHash[bucket].end(),key);
    if(it == setHash[bucket].end()){
        setHash[bucket].push_back(key);
    }
}

void remove(int key) {
    int bucket = key % 10000;
    vector<int>::iterator it1;
    it1 = find(setHash[bucket].begin(),setHash[bucket].end(),key);
    if(it1 != setHash[bucket].end()){
        int index = distance(it1,setHash[bucket].begin());
        setHash[bucket].erase(setHash[bucket].begin()+index);
    }

}

/** Returns true if this set did not already contain the specified element */
bool contains(int key) {
    int bucket = key % 10000;
    vector<int>::iterator it2;
    it2 = find(setHash[bucket].begin(),setHash[bucket].end(),key);
        if(it2 != setHash[bucket].end()){
            return true;
        }

    return false;
}
class MyHashSet {
public:
    void add(int key) {
        flags.set(key);
    }
    void remove(int key) {
        flags.reset(key);
    }
    bool contains(int key) const {
        return flags[key];
    }
private:
    bitset<1000000+1> flags;
};