求两个数组的交集,有很多解法,比如最暴力的 for
循环嵌套,接下来要实现的一种是利用 hash
的方式。这里不使用 OC
提供的 NSSet
,NSDictionary
。
具体实现思路:
说明:两个数组,分别称为第一个数组、第二个数组
用一个数组中元素的hash
值作为另一个新数组的下标,新建的数组要统一初始化,hash
到的下标里面的元素统一设置为1,再循环hash
另一个数组中的元素,用这个元素作为下标去新建的数组中取元素,如果能取到1则证明第二个数组中的这个元素在第一个数组中。hash
出来的数字比较大,用这个数对数组的个数求余数。
-
新建一个数组,数组的大小选用第一个数组和第二个数组中个数少的那一个,因为此时另开辟了内存,要少开辟一点,并初始化,如果担心发生
hash
碰撞,可以稍微将新建数组的容量扩大一点。 -
选择数量少的一个数组,循环获取这个数组中元素的 hash 值,并用这个 hash 值对数组的个数求余数得到下标
index
,用index
这个下标访问数组,在这个下标的位置存储1。 -
循环另一个数组,
hash
里面的元素并用这个值对新建数组的个数求余数,得出新的下标index2
,用index2
作为下标,去刚才新建的数组中获取元素,如果获取到的元素是1,那么久找到了,否则没找到。
具体代码如下:
- (void)viewDidLoad {
[super viewDidLoad];
NSArray<NSNumber *> *array1 = @[@"1",@"2",@"3",@"4"];
NSArray<NSNumber *> *array2 = @[@"1",@"2",@"3",@"4"];
int hashArray[8];
memset(hashArray, 0, sizeof(hashArray));
for (int i=0; i<array1.count; i++) {
int index = CFHash((__bridge CFTypeRef)(array1[i]))%8;
hashArray[index] = 1;
}
for (int i=0; i<array2.count; i++) {
int index = CFHash((__bridge CFTypeRef)array2[i])%8;
if (hashArray[index] == 1) {
NSLog(@"same num: %@", array2[i]);
}
}
}
具体执行结果及数组的存储内容如下图:

网友评论