Objective c 如何在NSArray上执行二进制搜索?
对(已)排序的Objective c 如何在NSArray上执行二进制搜索?,objective-c,ios,algorithm,nsarray,binary-search,Objective C,Ios,Algorithm,Nsarray,Binary Search,对(已)排序的NSArray进行二进制搜索的最简单方法是什么 到目前为止,我发现的一些潜在方法包括: 使用cfarraySearchValues(已提及)-这是否适用于NSArray 方法indexOfObject:insertedrange:options:usingComparator:ofNSArray假设数组已排序,并采用类型为NSBinarySearchingOptions的opts参数-这是否意味着它执行二进制搜索?他们只是说: 返回与使用给定NSComparator块的数组中的元
NSArray
进行二进制搜索的最简单方法是什么
到目前为止,我发现的一些潜在方法包括:
cfarraySearchValues
(已提及)-这是否适用于NSArray
indexOfObject:insertedrange:options:usingComparator:
ofNSArray
假设数组已排序,并采用类型为NSBinarySearchingOptions
的opts
参数-这是否意味着它执行二进制搜索?他们只是说:
返回与使用给定NSComparator块的数组中的元素进行比较的对象在指定范围内的索引
提前感谢。
cfarraySearchValues
应该可以工作-NSArray*
与CFArrayRef
1和2都可以工作#2可能更容易;除了二进制搜索(比如说,如果范围大于某个大小),该方法做任何事情都毫无意义。您可以在大型阵列上验证它只执行少量比较 第二种选择肯定是最简单的。Ole Begemann有一篇关于如何使用NSArray
的indexOfObject:insertedrange:options:usingComparator:
方法的博客:
NSArray *sortedArray = ... // must be sorted
id searchObject = ...
NSRange searchRange = NSMakeRange(0, [sortedArray count]);
NSUInteger findIndex = [sortedArray indexOfObject:searchObject
inSortedRange:searchRange
options:NSBinarySearchingFirstEqual
usingComparator:^(id obj1, id obj2)
{
return [obj1 compare:obj2];
}];
参阅
< P>我惊讶的是没有人提到使用它,当它包含有适当散列的对象,比如大多数基础数据类型时,执行恒定的时间查找。与其将对象添加到数组中,不如先将其添加到集合中(如果出于其他目的需要保留排序顺序[或者在iOS 5.0或Mac OS X 10.7上需要保留排序顺序],也可以将其同时添加到集合中) 要确定集合中是否存在对象,请执行以下操作: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).
重要的是要知道,如果每次执行查找时都将数组转换为集合,则会失去任何性能优势,理想情况下,您将使用包含要测试的对象的预构造集合。//方法传递我们正在搜索的数组和编号。
//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.
}
-(void)二进制搜索:(NSArray*)数组编号输入:(NSNumber*)键{
NSU整数最小索引=0;
nsuiger maxIndex=array.count-1;
nsuiger midIndex=array.count/2;
NSNumber*minIndexValue=数组[minIndex];
NSNumber*midIndexValue=数组[midIndex];
NSNumber*maxIndexValue=数组[maxIndex];
//检查以确保数组在边界内
如果(键>最大索引值| |键<最小索引值){
NSLog(@“密钥不在范围内”);
返回;
}
NSLog(@“中间索引值为%@”,中间索引值为%@);
//若key小于middleIndexValue,那个么sliceUpArray并再次递归调用该方法
if(键midIndexValue){
NSArray*slicedArray=[数组子数组WithRange:NSMakeRange(midIndex+1,array.count/2)];
NSLog(@“切片数组为%@”,切片数组为%@);
[自二进制搜索:slicedArray Number输入:键];
}否则{
//找到了其他号码
NSLog(@“找到的编号”);
}
}
//调用方法
@界面视图控制器()
@属性(非原子)NSArray*searchArray;
@结束
-(无效)viewDidLoad{
[超级视图下载];
//用10个值初始化数组
self.searchArray=@[@1,2,3,4,5,6,7,8,9,10];
//调用方法并搜索任意号码
[self binarySearch:self.searchArray number输入:@5];
//加载视图后,通常从nib执行任何其他设置。
}
为什么不改用NSDictionary?objectForKey:我会搜索你的。关于这一点有几个问题-对于对象搜索来说,字典比数组有什么好处?另外,为了使用您建议的方法,我不需要知道对象的键吗?首先,我在数组中搜索对象的原因是我不知道它的索引-如果我改为字典实现,这意味着我不知道键。这就是我的想法-文档似乎有点缺乏,因为它们实际上没有声明它执行二进制搜索(他们只是强烈建议)。如果我开始做你建议的测试,我一定会在这里公布结果。请记住,如果以后使用findIndex,你必须确保findIndex低于[SortedDarray count]。如果项目不存在,并且您尝试使用sortedArray[findIndex]获取它,则此操作将崩溃。是的!这是一个非常优雅的解决方案。