【问题标题】:Checking a series of numbers for consistency检查一系列数字的一致性
【发布时间】:2012-03-25 17:07:59
【问题描述】:

我维护一个整数数组。重要的是,此数组中的整数始终从 0 开始按顺序排列。例如,如果数组中有 5 个整数,则它们的值必须是 0、1、2、3、4(尽管顺序不限)。

我想设计一个简单、有效的方法来检查这一点。如果数组包含从 0 到 array.count - 1 的所有正整数,它将返回 true。

我很想听听一些不同的想法来处理这个问题!

【问题讨论】:

  • 如果您需要确定,最好的办法就是遍历数组中的每个元素并检查。因此,只需从 0 数到数组的长度减一,并检查数组的位置 i 中的值是否实际上是值 i。 (唯一的“优化”是在遇到不应该的元素时返回 false,而不是继续计数)。编辑:哦,而且,Mathias 提出了一个很好的观点:无论如何保留这个数组有什么意义?你很清楚如何计算n 以下的每一个自然数,那么为什么要把它们全部存储起来呢?
  • 你用这个数组做什么?保持数组的上限,并迭代整数不是更容易吗?
  • 我使用数组来填充表格视图。数字是排序顺序。我以不同的方式将项目放入和移出部分,并且只想要一种方法来确保我正确设置排序顺序,以便在我将项目移入/移出部分后,没有间隙等。我会发布我目前在做什么——我认为它符合你的建议。只是想知道是否有更巧妙的方法(例如,我正在研究对数字求和并与斐波那契数列进行比较 - 可能效率不高,但可能很有趣)。
  • @gspr - 我不太关心订单,所以我使用 containsObject 而不是 objectForIndex

标签: objective-c ios math nsarray logic


【解决方案1】:

或者,给定整数 [0..N-1],如果你依次将 2 提高到每个整数的幂,总和将是 -1+2^N。这不是任何其他 N 个整数集合所具有的属性。

我提供了这个作为替代方案,没有声称适用性、性能或效率,而且我认识到随着 N 变大会出现问题。

【讨论】:

    【解决方案2】:

    基本上,您要测试的是您的数组是否是[0...n-1] 的排列。有一些简单的算法在时间和内存上都是O(n)。例如,请参见 PDF file

    有时我会使用一个非常简单的检查,即时间为O(n),内存中为O(1)。理论上它可以返回误报,但它是发现大多数错误的好方法。它基于以下事实:

    0 + 1 + 2 + ... + n-1 == n * (n-1) / 2
    0 + 1² + 2² + ... + (n-1)² == n * (n-1) * (2 * n - 1) / 6
    

    我不知道objective-c,但代码在C#中应该是这样的:

    bool IsPermutation(int[] array)
    {
        long length = array.Length;
        long total1 = 0;
        long total2 = 0;
    
        for (int i = 0; i<length; i++)
        {
            total1 += array[i];
            total2 += (long)array[i] * array[i];
        }
    
        return 
           2 * total1 == length * (length - 1) &&
           6 * total2 == length * (length - 1) * (2 * length - 1);
    }
    

    【讨论】:

      【解决方案3】:

      这与您的 itemsSequencedCorrectlyInSet: 方法没有太大区别,但它使用可变索引集,这将比执行 -[NSSet containsObject:] 更快。在您拥有数千个表行之前,可能不是问题。无论如何,这里的关键见解是鸽子洞原理说,如果你有 N 个小于 N 的整数并且没有一个是重复的,那么你每个 0...N-1 都只有一次。

      -(BOOL)listIsValid:(NSArray*)list
      {
          NSMutableIndexSet* seen = [NSMutableIndexSet indexSet];
      
          for ( NSNumber* number in list )
          {
              NSUInteger n = [number unsignedIntegerValue];
      
              if ( n >= [array count] || [seen containsIndex:n] )
                  return NO;
      
              [seen addIndex:n];
          }
      
          return YES;
      }
      

      【讨论】:

      • 既然我在我的问题中提到了“高效”,而且这似乎是最务实的,我会接受它。谢谢!
      【解决方案4】:

      这是我当前的实现(testSet 是一组 NSNumber)-

          - (BOOL)itemsSequencedCorrectlyInSet:(NSSet *)testSet{
              for (NSInteger i = 0; i < testSet.count; i++) {
                     if (![testSet containsObject:[NSNumber numberWithInteger:i]]) {
                          return NO;
                     }
               }
      
               return YES;
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-07-20
        • 2019-04-08
        • 1970-01-01
        • 2022-07-21
        • 1970-01-01
        • 1970-01-01
        • 2011-02-19
        • 2019-12-31
        相关资源
        最近更新 更多