【问题标题】:Find the largest number from NSArray that is smaller than the given number从 NSArray 中找到小于给定数字的最大数字
【发布时间】:2014-08-11 07:39:41
【问题描述】:

假设我有一个排序的整数数组 int[],我想搜索最接近某个输入数字的较小值。

例如,如果数组包含1235759120,并且输入为109,则输出应为59。 我已经尝试过了,但它没有按需要工作。

NSTimeInterval currentTime = self.player.currentTime;
NSInteger playerTime=currentTime;
NSUInteger index = [_timesArray indexOfObject:@(playerTime)
                                inSortedRange:NSMakeRange(0, _timesArray.count-1)
                                      options:NSBinarySearchingFirstEqual | NSBinarySearchingInsertionIndex
                              usingComparator:^(id a, id b) {
                                  return [a compare:b];
                              }];

【问题讨论】:

  • 你已经对数组进行了排序,你需要的是从最大数到最小数……算法在这里很简单!

标签: objective-c sorting search nsarray


【解决方案1】:

您的代码确实与您提供的示例数据一样工作:

NSArray *_timesArray = @[@1, @23, @57, @59, @120];
NSTimeInterval currentTime = 109;
NSInteger playerTime=currentTime;
NSUInteger index = [_timesArray indexOfObject:@(playerTime)
                                inSortedRange:NSMakeRange(0, _timesArray.count-1)
                                      options:NSBinarySearchingFirstEqual | NSBinarySearchingInsertionIndex
                              usingComparator:^(id a, id b) {
                                  return [a compare:b];
                              }];
NSLog(@"Index: %lu", (unsigned long)index);

输出:

Index: 4

检查您的输入。他们可能不是你想的那样。

【讨论】:

  • 索引等于 4 表示 120 值。
  • 不,索引 4 并不意味着 120。 indexOfObject:inSortedRange:options:usingComparator: 的输出是应该插入对象的索引。 “如果指定了 NSBinarySearchingInsertionIndex 选项,则返回您应该插入 obj 的索引以维护排序数组。”请参阅 Apple 文档:developer.apple.com/library/mac/documentation/Cocoa/Reference/…:
【解决方案2】:

正如我之前所说:“你已经对数组进行了排序,你需要的是从最大数到最小数……算法在这里很简单!”

    NSNumber* givenNumber = @(105);
    for (NSNumber* item in [@[@(1), @(23), @(57), @(59), @(120)] reverseObjectEnumerator]){
        // go downward
        if (item.integerValue < givenNumber.integerValue)
        {
            NSLog(@"%@ < %@",item,givenNumber);
            // save this number somewhere
            break;
        }
    }

【讨论】:

  • 这只是对 indexOfObject:inSortedRange:options:usingComparator: 进行的搜索的较慢重新实现。问题不在于苹果提供的方法搜索不正确……
【解决方案3】:

它可以通过在 O(lg n) 中运行的 binary_search_like 算法来解决,但我不知道 Objective-c,所以我将在 c++ 中给出代码。

我假设给定的元素不在数组中。

int binary_search_like(int s[], int key, int low, int high)
{
    int middle; 
    if (low > high) return (s[high]); 

    middle = (low + high) / 2;

    if (s[middle] > key)
        return(binary_search_like(s, key, low, middle - 1));
    else
        return(binary_search_like(s, key, middle + 1, high));
}

int Search(int s[], int key, int size){

    if (key > s[size - 1]) return s[size - 1];
    // Check if key < smallest element , give error !

    return binary_search_like(s, key, 0, size);

 }

【讨论】:

  • 问题中给出的示例代码 (indexOfObject:inSortedRange:options:usingComparator:) 已经在执行二进制搜索。无需用 C++ 编写自己的代码。
猜你喜欢
  • 1970-01-01
  • 2017-03-05
  • 2012-11-20
  • 1970-01-01
  • 1970-01-01
  • 2021-05-12
  • 2013-09-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多