【问题标题】:Hash table's finding function in c?哈希表在c中的查找功能?
【发布时间】:2015-09-12 15:37:48
【问题描述】:

问题出自《Data Structures and Algorithm Analysis in c》一书。在谈到哈希表时,作者展示了这样的查找函数:

Positon find(ElementType Key,HashTable H)
{
    Position CurrentPos;
    int CollisionNum;
    CollisionNum=0;
    CurrenPos=Hash(Key,T->TableSize)
    while(H->TheCells[CurrentPos].info!=Empty&&H->TheCells[CurrentPos].Element!=key)
    {
        CurrentPos+=2*++CollisionNum-1;
        if(CurrentPos>=H->TableSize)
            CurrentPos-=H->TableSize;
    }
    return CurrentPos;
}

作者在while句子中说判断条件的顺序,

H->TheCells[CurrentPos].info!=Empty && H->TheCells[CurrentPos].Element!=key

非常重要,不应该交换。但我不知道为什么。我已尝试交换订单,但该功能仍然正常工作。换单会有什么BUG?

【问题讨论】:

  • TheCells[CurrentPos] 结构的成员是什么?这个结构是如何定义的?
  • 顺便说一句,第一个条件必须在第二个条件之前进行评估。这肯定与此有关。 (如果第一个适用,则第二个评估。这称为短路评估。)
  • 一般情况下,不能切换短路运算符的操作数。但我认为这里没有任何问题。
  • TheCells 是一个指向数组的指针,里面存储了元素
  • 我能看到的唯一问题是Element 是否可能具有陷阱值,因此仅将其与另一个值进行比较将是未定义的行为。

标签: c data-structures hashtable


【解决方案1】:

假设您编写了多个条件,例如condition1 && condition2 && ...。这些是从左到右评估的。如果这些条件中的任何一个评估为 false,则不会评估右侧的其余条件。

现在您还没有向我们提供有关您的代码中使用的结构的足够信息,但是如果该单元格的 .Element 没有被指定,那么假设该单元格的 .info 包含 Empty 似乎是合理的。初始化。

如果我们写

H->TheCells[CurrentPos].info!=Empty && H->TheCells[CurrentPos].Element!=key

那么我们首先检查.Element 是否已经初始化。只有这样,我们才会继续将其值与key 进行比较。如果不是,那么.Element 将永远不会被访问。

但是如果我们写

 H->TheCells[CurrentPos].Element!=key && H->TheCells[CurrentPos].info!=Empty

可能会有问题。假设当前单元格的.Element 尚未初始化。第一个条件访问.Element 以将其与key 进行比较。这可能会导致未定义的行为。

【讨论】:

    【解决方案2】:

    如果没有更多细节,我的猜测是如果H->TheCells[CurrentPos].infoEmpty,那么H->TheCells[CurrentPos].Element 是没有意义的(可能没有初始化?),因此评估它会导致错误。

    这是这种模式的一个(有点愚蠢/极端的)示例:

    char *dst = NULL;
    if (dst != NULL && memcpy(dst, "foo", strlen("foo" +1))) // this is OK
        // do stuff
    memcpy(dst, "foo", strlen("foo" +1)); // segfault here!!!
    

    这里有一些(不太傻的)伪代码来理解这个想法:

    if (something.has_a_value == true && something.value == value_I_look_for)
        // then proceed
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-09
      • 2011-11-11
      • 1970-01-01
      • 1970-01-01
      • 2019-01-03
      • 2012-05-24
      • 2018-04-03
      • 2016-04-03
      相关资源
      最近更新 更多