64位数组操作的C/ c++

64bit array operation by C/C++

本文关键字:c++ 数组 操作 64位      更新时间:2023-10-16

我有一个效率关键应用程序,我需要这样一个数组类型的数据结构A。键为0, 1, 2,...,值为uint64_t distinct值。我需要两个常量操作:

1. Given i, return A[i];
2. Given val, return i such that A[i] == val

我不喜欢使用哈希表。因为我尝试了GLib GHashTable,它花了大约20分钟将6000万个值加载到哈希表中(如果我删除插入语句,它只花了大约6秒)。这个时间不适合我的申请。或者有人推荐其他哈希表库?我试了一下uthash.c,它马上崩溃了。

我也试过SDArray,但它似乎不是正确的。

有谁知道什么数据结构能满足我的要求吗?或者有有效的哈希表实现吗?我更喜欢用C/c++。

谢谢。

通常,您需要两个散列表来完成此任务。如您所知,哈希表在预期的常数时间内为您提供查找。查找需要遍历整个数据结构,因为关于值的信息没有编码在哈希查找表中。

使用两个哈希表:一个用于键-值,另一个(反向)用于值-键查找。在您的特殊情况下,只要键是"顺序的",就可以使用向量进行前向搜索。但是,这并不改变对支持快速反向查找的数据结构的需求。

关于哈希表的实现:在c++ 11中,您可以使用新的标准容器std::unordererd_map

实现可能是这样的(当然这是可以调整的,比如引入const-正确性,通过引用调用等):

std::unordered_map<K,T> kvMap; // hash table for forward search
std::unordered_map<T,K> vkMap; // hash table for backward search
void insert(std::pair<K,T> item) {
    kvMap.insert(item);
    vkMap.insert(std::make_pair(item.second, item.first));
}
// expected O(1)
T valueForKey(K key) {
    return kvMap[key];
}
// expected O(1)
K keyForValue(T value) {
    return vkMap[value];
}

一个干净的c++ 11实现应该"包裹"在键值哈希映射周围,这样你在包装器类中就有了"标准"接口。始终保持反向映射与正向映射同步。

关于创建性能:在大多数实现中,有一种方法可以告诉数据结构要插入多少元素,称为"保留"。对于哈希表,这是一个巨大的性能优势,因为动态调整数据结构的大小(在插入过程中不时发生)完全重新构建了整个哈希表,因为它改变了哈希函数本身。

我会选择两个向量(假设你的值确实不同),因为在访问中这是O(1)而map在访问中是O(log n)

vector<uint64_t> values;
vector<size_t> keys
values.reserve(maxSize); // do memory reservation first, so reallocation doesn't occur during reading of data
keys.reserve(maxSize); // do memory reservation first, so reallocation doesn't occur during reading of data

当读取数据

时,
values[keyRead] = data;
keys[valueRead] = key;

读取信息则相同

data = values[currentKey];
key = keys[currentData];