【发布时间】:2011-11-06 23:00:00
【问题描述】:
我有两个数组,但它们有不同的长度。我想比较这两个数组并将常用项放入一个新数组。同时不应该有重复项是第三个数组。 我真的搞砸了,请帮帮我。 非常感谢。 . .
【问题讨论】:
标签: iphone objective-c ios iphone-sdk-3.0
我有两个数组,但它们有不同的长度。我想比较这两个数组并将常用项放入一个新数组。同时不应该有重复项是第三个数组。 我真的搞砸了,请帮帮我。 非常感谢。 . .
【问题讨论】:
标签: iphone objective-c ios iphone-sdk-3.0
这样的?
NSMutableSet* set1 = [NSMutableSet setWithArray:array1];
NSMutableSet* set2 = [NSMutableSet setWithArray:array2];
[set1 intersectSet:set2]; //this will give you only the objects that are in both sets
NSArray* result = [set1 allObjects];
这样做的好处是不查找数组中的对象,而循环遍历另一个数组,该数组具有 N^2 复杂性,如果数组很大,可能需要一段时间。
编辑:set2 不必是可变的,不妨只使用
NSSet* set2 = [NSSet setWithArray:array2];
【讨论】:
intersectSet: 将不得不做类似的事情(检查项目并比较),但它对其进行了优化,因此最终可能会更快地复制所有这些项目都在集合周围,往返集合。 OTOH,Akshay 提出的简单循环,可能会更快,因为它不会复制太多。必须针对需要的情况分析这两种方法。
containsObject: 的简单循环。我的方法大约需要。是使用集合的 1.5 倍。
第三种方法(除了使用集合或使用包含检查每个项目的简单循环之外)是对两个数组进行排序,然后使用两个索引:
// approach using sets:
NSArray *arrayUsingSets(NSMutableArray *arr1, NSMutableArray *arr2)
{
NSMutableSet *set1 = [NSMutableSet setWithArray: arr1];
NSSet *set2 = [NSSet setWithArray: arr2];
[set1 intersectSet: set2];
return [set1 allObjects];
}
// my approach:
NSArray *arrayUsingComp(NSMutableArray *arr1, NSMutableArray *arr2)
{
NSMutableArray *results = [NSMutableArray arrayWithCapacity: arr1.count + arr2.count];
// Assumes input arrays are sorted. If not, uncomment following two lines.
// [arr1 sortUsingSelector: @selector(compare:)];
// [arr2 sortUsingSelector: @selector(compare:)];
int i = 0;
int j = 0;
while ((i < arr1.count) && (j < arr2.count))
{
switch ([[arr1 objectAtIndex: i] compare: [arr2 objectAtIndex: j]])
{
case NSOrderedSame:
[results addObject: [arr1 objectAtIndex: i]];
i++, j++;
break;
case NSOrderedAscending:
i++;
break;
case NSOrderedDescending:
j++;
break;
}
}
// NOTE: results are sorted too.
// NOTE 2: loop must go "backward".
for (NSInteger k = results.count - 1; k > 0; k--)
if ([[results objectAtIndex: k] isEqual: [results objectAtIndex: k-1]])
[results removeObjectAtIndex: k];
return results;
}
我做了一些简单的分析,如果我对传入的数组制作可变副本并对其进行排序,它的执行速度比使用集合的方法慢 1.5 倍。我上面的方法似乎比使用集合的方法执行速度快 1.5 倍。如果保证数组已经排序,我的方法将执行得更好(几乎是使用集合的版本的 4 倍),因为不需要排序。
更新:
这并没有消除重复,所以我在例程的末尾添加了循环。现在它只比使用集合的方法快 3 倍,但仍然...
【讨论】:
遍历array1并在array2中搜索它。如果找到,则将其添加到 array3,如果它还没有。
for (MyObject* obj in array1)
{
if([array2 containsObject:obj] && ![array3 containsObject:obj])
[array3 addObject:obj];
}
如果您的 array1 没有重复项,则不需要第二次检查。
【讨论】: