数组是一种极其简单的数据结构。在内存中,它是一个简单的连续块。假设数组中的每个项目都是四个字节,并且数组有 100 个元素的空间。那么数组只是内存中的 400 个连续字节,分配给数组的变量是指向第一个元素的指针。假设这是内存中的位置 10000。
当您访问数组的元素 #3 时,如下所示:
myarray[3] = 17;
...发生的事情非常简单:将 3 乘以元素大小(4 字节)添加到基指针。在此示例中,它是 10000 + 3 * 4 = 10012。然后您只需写入位于地址 10012 的 4 个字节。非常简单的数学运算。
哈希表不是基本数据结构。它可以以多种方式实现,但简单的一种可能是 256 个列表的数组。然后当你访问哈希表时,首先你要计算你的键的哈希值,然后在数组中查找正确的列表,最后沿着列表查找正确的元素。这是一个复杂得多的过程。
一个简单的数组总是比哈希表快。您引用的文字是,如果数据非常稀疏......您可能需要一个非常大的数组来进行这个简单的计算。在这种情况下,您可以使用更少的内存空间来保存哈希表。
考虑一下你的字符是否是 Unicode——每个字符两个字节。那是 65536 个可能的字符。并假设您只谈论具有 256 个或更少字符的字符串。要使用数组计算这些字符,您需要创建一个包含 64K 元素的数组,每个元素一个字节......占用 64K 内存。另一方面,像我上面提到的那样实现的哈希表可能只占用 4*64 字节的列表指针数组,然后每个列表元素占用 5-8 个字节。因此,如果您正在处理一个包含 64 个唯一 Unicode 字符的 256 个字符的字符串,那么它总共最多占用 768 个字节。在这些条件下,哈希表将使用更少的内存。但它总是会变慢。
最后,在你展示的简单案例中,你可能只是在谈论拉丁字母,所以如果你强制使用小写字母,你可以有一个只有 26 个元素的数组,并让它们尽可能大,这样你就可以计算出尽可能多的元素您需要的字符。即使是 40 亿,您也只需要 26 * 4 = 104 个字符数组。所以这绝对是去这里的方式。