【问题标题】:implement linear probing in c++ for a generic type在 C++ 中为泛型类型实现线性探测
【发布时间】:2016-10-10 08:05:22
【问题描述】:

我想在 C++ 中实现 hashtabe 的线性探测,但是键、值 pair 将是通用类型,例如:vector >(其中 key,value 是通用类型)。

现在,在线性探测中,如果某个单元格被占用,我们会遍历向量,直到找到一个空单元格,然后将新的对放入该单元格中。

问题是,在泛型类型中,我如何能够检查特定单元格是否被占用? 我不能使用这些条件:

if(key == '\0')//As key is not of type string 

if(key == 0)//As key is not of type int

那么,如何检查向量中的特定单元格是否为空? 如果我误解了这个概念,请纠正我。

【问题讨论】:

  • 您可以专门化包含该代码的函数。
  • 您可能需要另一个知道自己是否为“空”的数据结构。
  • 但是我怎样才能专门化这个功能呢?
  • 将一个额外的标志与单元格相关联,最好作为一个压缩的位数组。
  • 你不能。有些事情 C++ 不允许你做。您当然可以构建一个并行的标志数组,但这并不能真正回答问题。您只能要求您的模板类型支持某种描述的“isnull”方法,然后代码不是通用的。

标签: c++ templates hashtable linear-probing


【解决方案1】:

我认为您可以检查向量的元素是否具有有意义的键和值:

if(vector[i] == std::pair<key, value>())
    //empty

或者,如果您只关心按键

if(vector[i].first == key())
    //empty

这种方法假定key 类型的默认构造函数构造了一个对象,该对象将被视为“空”或“无效”键。

【讨论】:

  • 如果keyvalue 没有默认值会怎样?例如int
  • @FatihBAKIR,他们为什么不呢?在这种情况下,int 将被初始化为 0。当然,这种方法假定key 类型的默认构造函数创建了一个对象,该对象被认为是emptyinvalid 键。编辑了答案以强调这一点。
  • @SingerOfTheFall,我应该为向量的每个索引创建一个空对(在构造函数中)吗?这不会限制应该事先知道向量的大小。
  • @Saurabh,不一定。您只需要确保当向量中的元素被删除时,您要么 1) 真正从向量中删除它,要么 2) 替换为空对。这样,当您稍后遍历向量时,您将在某处找到一个空对并使用该单元格,到达向量的末尾,并附加到它。
  • @SingerOfTheFall,还有一件事。我相应地编写了一些代码,请参阅链接:(gist.github.com/Sharma96/f312af6b3219c992dd1519a572dfddf3)。代码中发生了一件奇怪的事情,如果你会运行代码,您会发现,当 y(在 ch 函数中)的值为 5 时,它为值 v[y] 打印 135057。首先,它如何在第 5 个索引处初始化该对的值(并且只有第 5 个索引),而我只调用了 4 次 add 函数。
【解决方案2】:

您可以使用免费函数isEmpty 来检查键类型是否为空。定义一个适用于大多数类型的模板化默认函数,并制作默认无法处理的特殊函数。

例如

template<typename T>
bool isEmpty(const T &t) {
    return !t;
}

bool isEmpty(const std::string &s) {
   return s.length() == 0;
}

bool isEmpty(double d) {
    return d < 0;
}

isEmpty(0); // true
isEmpty(1); // false
isEmpty(std::string()); // true
isEmpty(std::string("not empty")); // false
isEmpty(1.0); // false
isEmpty(-1.0); // true

您只需要专门针对没有operator ! 或需要不同逻辑进行检查的键类型

【讨论】:

    【解决方案3】:

    如果您不想排除在哈希中包含“默认构造”元素的可能性,您可以构建一个并行数据结构,例如 std::bitset(如果您事先知道数据的最大大小结构)或std::vector&lt;bool&gt;,在下面我将调用has。如果vector[i] 包含一个有效的、实际插入的元素,has[i] 将为真。

    所以操作应该修改如下:

    • 插入:继续扫描向量,直到找到i 这样的位置has[i] == false
    • 删除位置 i 的元素:将 has[i] 设置为 false

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 2020-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-17
      • 1970-01-01
      相关资源
      最近更新 更多