C 使用什么数据结构?(哈希映射与trie与?)
我有一个C函数,它可以生成大约600万个独特的数组。这些数组始终每个都有17个元素,每个元素都是0到16之间的整数。我还有一个稍微修改过的函数版本,它还将生成大约600万个相同类型的独特阵列。我的问题是,第二个比第一个少产生45000个结果,我想看看这些结果是什么 所以我的方法是简单地存储第二个函数的所有结果(计算器告诉我这不应该超过400 mb,这可以保存在内存中),然后查找第一个函数的结果,打印出不存在的结果 假设一般的方法是有意义的(如果没有,请告诉我),我要寻找的是一个合适的数据结构(最好是用C语言实现的),它可以容纳大约600万个数据的唯一排列C 使用什么数据结构?(哈希映射与trie与?),c,data-structures,hashmap,trie,C,Data Structures,Hashmap,Trie,我有一个C函数,它可以生成大约600万个独特的数组。这些数组始终每个都有17个元素,每个元素都是0到16之间的整数。我还有一个稍微修改过的函数版本,它还将生成大约600万个相同类型的独特阵列。我的问题是,第二个比第一个少产生45000个结果,我想看看这些结果是什么 所以我的方法是简单地存储第二个函数的所有结果(计算器告诉我这不应该超过400 mb,这可以保存在内存中),然后查找第一个函数的结果,打印出不存在的结果 假设一般的方法是有意义的(如果没有,请告诉我),我要寻找的是一个合适的数据结构(最
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
(或其某些转换),然后对其执行快速成员资格测试。正如标题所说,我确实怀疑哪些数据结构可以完成这项工作,但我不确定尝试或哈希图是否是最佳选择
这是一种检测另一种算法中缺陷的算法,而不是将在生产中使用的算法。我感兴趣的是以一种编码的方式来完成这项工作,并以人的方式相对快速地返回结果,而不一定是以毫秒为单位,因此,存在能够完成大部分工作的易于搜索的库肯定是一个优势。取决于您的情况下哪一个库可以获得更好的内存性能。另外,您使用什么样的散列函数,如何解决冲突等。检查一个最优性如何取决于排列的分布方式以及插入与搜索的比率。因为你不关心最优性,只想用一种简单的方法来检验假设,而不必整夜等待结果,我的直觉说: 整数[0,16]可以表示为五位数字,因此其中十七位可以表示为85位(11字节)的二进制字符串。因此,您可以使用许多库中的一个来存储经过排序/哈希处理的字符串集,并对其进行成员资格测试,这是可以完成的。它的速度和缓存一致性不如调优的trie,但它足以在几秒钟内完成66mb的数据,午餐前就可以完成 如果没有这样的库可以方便地使用,并且您必须从头开始工作,那么我只需要创建一个字符串的排序列表,然后通过二进制搜索进行成员资格测试。结果是O(n logn+m(n logn))=O(2×mn logn)eg,二次时间为m→N如果这只是在生产过程中作为脱机作业运行一次或两次,那就足够了;如果您打算一天不止一次地执行此操作,我会担心缓存的局部性,并使用trie或B树。保持简单:
- 将每个排列表示为17字节的数组
- 将整个较小的集合存储为上述数组(17*6M<98MB)
- 按字典顺序对其排序,这样
的比较器只需调用qsort
memcmp(左、右、17)
- 对于较大集合中的每个元素,使用二进制切块在排序数组中查找它(使用与前面相同的比较器,这次使用
)bsearch
最后两个步骤中的每一步都将执行大约6M*log(6M)的比较,即大约138M。这可能比编写代码所需的时间还要少。这并不长,因为一切都很简单:-)@Steve Jessop您可以在线性时间内完成最后一步,通过删除我们正在搜索的数组中不需要的值来进行更智能的搜索: 假设n是A的大小,m是B的大小
int counter_A = 0;
int counter_B = 0;
int counter_C = 0;
while(counter_A != n){
int temp = A[counter_A];
counter_A++;
//Removes all elements at the beginning of B since they are inferior than all
//elements in A because they are inferior than the minimum of A
for(;counter_B < m && B[counter_B] < temp;counter_B++);
if((counter_B < m && B[counter_B] > temp) || counter_B == m){
C[counter_C] = temp;
counter_C++;
}
}
int计数器A=0;
int计数器_B=0;
int计数器_C=0;
while(计数器A!=n){
int temp=A[计数器A];
计数器A++;
//删除B开头的所有元素,因为它们低于所有元素
//A中的元素,因为它们低于A的最小值
对于(;counter_Btemp)|计数器B==m){
C[计数器C]=温度;
计数器C++;
}
}
这应该在O(n+m)时间内执行,因为算法的每一步都至少执行一次计数器递增。我认为您需要权衡C中的值,以避免通信 我将把C中的每个数组逐行打印为空格分隔的整数。然后从文件中加载它,创建一组字节数组,如下所示(F代码): 然后计算两个文件之间的集差,如下所示:
load "file1.txt" - load "file2.txt"
这可能需要几分钟才能运行。a)创建一个包含两个64位int的结构
b) 因为每个结果有17个元素,所以将前8个元素相乘,将结果放在第一个整数上,将其他7个元素相乘,将结果放在第二个整数上
c) 为您的结构创建运算符<
d) 创建一组结构并插入第一次运行的所有结果
e) 迭代第二次运行结果并执行set::find()
类结果
{
公众:
结果(int arr[17]);//填写_n1和_n2
布尔运算符<(常量结果和r)常量//比较
{
如果(_n1!=r._n1)
返回_n1SetResult;
SetResult SetResult;
Edwin到目前为止,我还没有哈希函数。我对问题进行了编辑,以表明数组是唯一生成的,因此不应该发生冲突(如果我正确理解注释的话)。哈希的性能将取决于哈希函数以及它们将数组映射到的哈希位置,这将决定所需内存的范围。特里肯
load "file1.txt" - load "file2.txt"
class Result
{
public:
Result(int arr[17]); // Fill-in _n1 and _n2
bool operator < (const Result& r) const // Compare
{
if (_n1 != r._n1)
return _n1 < r._n1;
return _n2 < r._n2;
}
protected:
int _n1;
int _n2;
};
typedef std::set< Result > SetResult;
SetResult setResult;