【问题标题】:Confused with the basics of Hash Table in C++对 C++ 中 Hash Table 的基础知识感到困惑
【发布时间】:2020-10-03 16:02:23
【问题描述】:

这是我写的关于哈希表的小代码。

#include <iostream>
using namespace std;

int hashval(int n){
    return n%5;
}


int main(){
    int hashtable[4],num, value;
    for (int i=0 ; i<=4; i++){
        hashtable[i]=0;
    }
    for (int i=0; i <=4; i++){
        cout << "Enter the number you wanna enter : ";
        cin>> num;
        value=hashval(num);
        while (hashtable[value]!=0){
            value=(value+1)%5;
        }
        hashtable[value]=num;
    }
     **// line A //** cout << hashtable[0] << "  " << hashtable[1] << "  " << hashtable[2] << "  " <<hashtable[3]<< "  " << hashtable[4] << "  " <<endl; 

    for (int j=0; j<=4; j=j+1){
    **// line B //**    cout << hashtable[j] << " ";  
    }

}

当我输入五个数字“13,15,18,29,30”时,A 行显示输出“15 29 30 13 18”。但是,B 行不显示最后一个元素,即显示的输出是“15 29 30 13 4”。 4从哪里来的?我很困惑为什么总是不打印最后一个元素,无论输入什么元素,而是打印一个不存在的元素。 A线和B线的功能不一样吗?我的代码有什么问题?任何帮助将不胜感激。谢谢!

【问题讨论】:

  • 你的数组太小了。
  • @BessieTheCow 你是什么意思?哪里太小了?
  • @Anon hashtable[4] 存储四 (4) 个值。您尝试在其中存储五个数字。
  • @Anon123 该数组只存储了 4 个值,因为数组的索引是 0、1、2 和 3。
  • @Anon123 int array[N] 是一个大小为 N 的数组,数组的第一个索引是 0。因此最大的有效索引是 N-1。非常多的新手知道前两个语句,但没有意识到它们暗示了第三个语句。

标签: c++ arrays hash output


【解决方案1】:

您的问题是int hashtable[4] 分配了一个数组,该数组可以存储四个值,索引为 0...3。但是,然后您尝试在数组中存储五个值。

通常 C++ 不太适合编译和查看的学习方法。在 C++ 中编译和测试代码是很常见的,当代码依赖于未定义的行为时,会发现代码“有效”。然而,在这种情况下,我们可以凭经验看到[4] 只为四个元素分配了足够的空间。以下代码将数组的大小除以其中一个元素的大小,计算数组可以存储的最大元素数。

#include <iostream>                                                                                                     
int main(){                                                                                                                     
  int a[4];                                                                                                               
  std::cout << (sizeof(a)/sizeof(a[0]));
  return 0;                                                                          
}

上面的代码输出4,表明int a[4]为4个元素分配了足够的空间。在包含 4 个元素的数组中存储 5 个元素会导致未定义的行为。

虽然我们可以在这里结束故事并只是说未定义的行为可以做任何事情,但有时了解(但不依赖于)超出数组的最常见副作用是有用的。通常发生的情况是您访问未分配的内存或分配给另一个变量的内存。请注意,在第一次和第二次打印hashtable[4] 之间,您分配了变量j,而当第二次访问hashtable[4] 时,j 恰好为4。可以肯定的是,由于您没有分配 hashtable[4] 所在的内存,编译器认为它未使用并将 j 放在那里。然后,当您打印 hashtable[4] 时,您实际上是在打印 j

强调未定义的行为意味着您不应该依赖编译和测试,这不是我的编译器发生的事情 (g++)。您的代码运行良好,甚至没有给出任何valgrind-Wall 警告。

数组太小,您的代码在我看来是正确的,所以如果您只是将 int hashtable[4] 更改为 int hashtable[5],您的代码应该可以在每个 C++ 编译器上正常工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-15
    • 2018-01-11
    相关资源
    最近更新 更多