这是我的代码,用于检查一个集合(a2)是否是另一个(a1)的子集。 在主函数中,数组被声明,然后传递给 isSubset 函数。 我创建了一个包含所有元素 0 的哈希数组,并首先按 a1 中的元素递增,然后 a2
now 计算哈希数组中值为 2 的元素。
string isSubset(int a1[], int a2[], int n, int m) {
int max=a1[0];
int count=0;
for(int i=0;i<n;i++){
if(a1[i]>max){
max=a1[i];
}
}
int hash[max+1]={0};
for(int i=0;i<n;i++){
hash[a1[i]]++;
}
for(int i=0;i<m;i++){
hash[a2[i]]++;
}
for(int i=0;i<max+1;i++){
if(hash[i]==2)
count++;
}
if(count==m)
return "Yes";
else return "No";
}
您获得SIGSEGV有几种潜在的可能性:
a1
为空或a2
为空n
大于a1
的大小,因此a1[i]
溢出并读取无效地址m
大于a1
的大小,因此a1[i]
溢出并读取无效地址int hash[max+1]={0};
需要一个堆栈hash
太大的缓冲区大小,这是不可用的。您可以在堆中分配hash
,也可以在.data
中分配静态。或者,您可能希望使用brk
系统调用来增加堆栈的可用内存。- 可能会导致
hash[a2[i]]
中的内存访问溢出。
a2[i]
大于max
,这我强烈建议您寻找如何实现哈希表。您可能对线性探测二次探测双哈希和单独链接感兴趣。 如果您厌倦了在静态哈希表中重新哈希,您可能需要签出可扩展哈希和线性哈希,它们采用本地重新分发而不是全局重新哈希。