用Cpp或其他快速语言反转大型哈希表
Invert Large Hash Table in Cpp or other fast language
我正在寻找高效的C++(或其他快速)来反转一个巨大的哈希表。
散列密钥的数量大约为200000000;并且每个散列密钥中的可能元素的数量为100000的数量级。
我想知道什么是(有效地)反转这样的表的好方法,这样现在元素就是键,键就是元素。
现在,我的硬盘驱动器中的数据存储在一个名为hash_file.txt的文件中
>1
T1
T3
T4
T100
>2
T4
T77
T9980
etc.
其中,>1,…,>200000000是原始哈希表的所有可能的密钥;以及T1,。。。,T100000是每个键的所有可能元素。注意:哈希表非常稀疏,每个键最多只有几百个元素。
输出的反向哈希表在本例中如下所示:
>T1
1
>T3
1
>T100
1
>T4
1
2
>T77
2
>T9980
2
我尝试了一些天真的代码,花了很长时间,内存用完了,所以我正在寻找好的建议。
这是一种非常简单的方法;值得一试(记得在启用优化的情况下进行构建,但最好不要禁用assert;-))。
#include <iostream>
#include <vector>
#include <cassert>
int main()
{
char c;
int n;
int key = -1;
const int max_t = 100000;
std::vector<std::vector<int>> v(max_t + 1);
while (std::cin >> c >> n)
if (c == '>')
key = n;
else
{
assert(c == 'T');
assert(key != -1);
assert(0 <= n && n < v.size());
v[n].push_back(key);
}
assert(std::cin.eof());
for (int i = 0; i < v.size(); ++i)
{
if (v[i].empty()) continue;
std::cout << ">T" << i << 'n';
for (int j = 0; j < v[i].size(); ++j)
std::cout << v[i][j] << 'n';
}
}
(输出顺序是数字的,而不是像你的问题中那样词典化的……如果你关心的话,你可以寻找/编写一个算法来迭代"i",以镜像词典化的顺序)
尽管你的问题是围绕着使用内存中的哈希来反转这些项的关系来提出的,但根据注释,你真正想做的只是获得输出,而方法并不重要。
由于您正在处理的数据量很大,因此无论您选择何种数据结构,都可能无法将其全部加载到内存中。因此,您将需要一种方法,该方法一次只将部分数据包含到内存中。
我倾向于使用数据库来完成这样的任务。创建一个包含两列的表——现有的"key"列和"T"value列。在值列上加一个索引。然后运行一个查询,该查询将为您提供所需的输出。
以下是我使用Postgresql:创建的一个示例
create table bigmap (
key integer,
value text
);
create index on bigmap(value);
insert into bigmap(key,value) values (1, 'T1');
insert into bigmap(key,value) values (1, 'T3');
insert into bigmap(key,value) values (1, 'T4');
insert into bigmap(key,value) values (1, 'T100');
insert into bigmap(key,value) values (2, 'T4');
insert into bigmap(key,value) values (2, 'T77');
insert into bigmap(key,value) values (2, 'T9980');
select value,key from bigmap order by value,key;
value | key
-------+-----
T1 | 1
T100 | 1
T3 | 1
T4 | 1
T4 | 2
T77 | 2
T9980 | 2
(7 rows)
从您的输入文件填充数据库应该相对简单。你可以用C++编写一个程序来完成这项工作,但根据你想多久做一次,你最好使用例如perl
使用数据库的优点是,它们已经有了对此类数据进行排序和索引的高效例程,并且还内置了在可用内存不足时使用临时文件准备大型查询结果的处理。
此外,如果你想找到特定T值的所有密钥,这很容易:
select value,key from bigmap where value='T100';
value | key
-------+-----
T100 | 1
(1 row)
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 如何将这个C++哈希表转换为动态扩展和收缩,而不是使用硬设置的最大值
- 用C++将哈希表写入文件并从文件中恢复
- C++中的并发哈希表
- 在具有开放寻址的哈希表中插入节点 [优化逻辑]
- 与C++哈希表的基础知识混淆
- 调整大小和复制哈希表数组中的元素
- 带链接的基本哈希表
- C++哈希表中,两个相同的实现,但一个给出错误
- 如果索引不是整数,我们如何在 C++ 中插入哈希表
- 查找项目在哈希表中的位置
- 为什么C++ STL 哈希表 (unordered_map) 不接受向量作为键
- C++哈希表 - 如何解决自定义数据类型作为键的unordered_map冲突?
- 使用哈希表设置实现
- 同时写入和读取哈希表
- 在 C++ 中为特定哈希表创建插入函数
- 我可以比朴素哈希表更快地将随机字符串映射到两个类吗?
- 哈希表:船舶记录
- 用Cpp或其他快速语言反转大型哈希表