对(已)排序NSArray
进行二进制搜索的最简单方法是什么?
到目前为止,我发现的一些潜在方式包括:
答案 0 :(得分:15)
第二种选择绝对是最简单的。 Ole Begemann有关于如何使用NSArray
的{{1}}方法的博客文章:
indexOfObject:inSortedRange:options:usingComparator:
答案 1 :(得分:7)
1和2都有效。 #2可能更容易;除了二进制搜索之外,对于该方法做任何事情当然没有意义(如果范围高于某个大小,比方说)。您可以在大型阵列上验证它只进行少量比较。
答案 2 :(得分:3)
CFArrayBSearchValues
应该有效 - NSArray *
toll-free bridged CFArrayRef
。{/ p>
答案 3 :(得分:3)
我很惊讶没有人提到使用NSSet
,[当它包含具有良好散列的对象时,例如大多数基础数据类型]执行恒定时间查找。不是将对象添加到数组中,而是将其添加到集合中(或者如果您需要为其他目的保留排序顺序,则将它们添加到两者中[或者在iOS 5.0或Mac OS X 10.7上有NSOrderedSet
])。
确定对象中是否存在对象:
NSSet *mySet = [NSSet setWithArray:myArray]; // try to do this step only once
if ([mySet containsObject:someObject])
{
// do something
}
可替换地:
NSSet *mySet = [NSSet setWithArray:myArray]; // try and do this step only once
id obj = [mySet member:someObject];
// obj is now set to nil if the object doesn't exist or it is
// set to an object that "isEqual:" to someObject (which could be
// someObject itself).
重要的是要知道,如果每次执行查找时将数组转换为集合,将会失去任何性能优势,理想情况下,您将使用包含要测试的对象的预构造集。
答案 4 :(得分:3)
//Method to pass array and number we are searching for.
- (void)binarySearch:(NSArray *)array numberToEnter:(NSNumber *)key{
NSUInteger minIndex = 0;
NSUInteger maxIndex = array.count-1;
NSUInteger midIndex = array.count/2;
NSNumber *minIndexValue = array[minIndex];
NSNumber *midIndexValue = array[midIndex];
NSNumber *maxIndexValue = array[maxIndex];
//Check to make sure array is within bounds
if (key > maxIndexValue || key < minIndexValue) {
NSLog(@"Key is not within Range");
return;
}
NSLog(@"Mid indexValue is %@", midIndexValue);
//If key is less than the middleIndexValue then sliceUpArray and recursively call method again
if (key < midIndexValue){
NSArray *slicedArray = [array subarrayWithRange:NSMakeRange(minIndex, array.count/2)];
NSLog(@"Sliced array is %@", slicedArray);
[self binarySearch:slicedArray numberToEnter:key];
//If key is greater than the middleIndexValue then sliceUpArray and recursively call method again
} else if (key > midIndexValue) {
NSArray *slicedArray = [array subarrayWithRange:NSMakeRange(midIndex+1, array.count/2)];
NSLog(@"Sliced array is %@", slicedArray);
[self binarySearch:slicedArray numberToEnter:key];
} else {
//Else number was found
NSLog(@"Number found");
}
}
//Call Method
@interface ViewController ()
@property(nonatomic)NSArray *searchArray;
@end
- (void)viewDidLoad {
[super viewDidLoad];
//Initialize the array with 10 values
self.searchArray = @[@1,@2,@3,@4,@5,@6,@7,@8,@9,@10];
//Call Method and search for any number
[self binarySearch:self.searchArray numberToEnter:@5];
// Do any additional setup after loading the view, typically from a nib.
}