检查一系列数字是否一致

时间:2012-03-25 17:07:59

标签: objective-c ios math nsarray logic

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

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

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

4 个答案:

答案 0 :(得分:3)

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

我提供此选项作为替代方案,不对适用性,性能或效率提出任何要求,并且我认识到当N变大时会出现问题。

答案 1 :(得分:1)

基本上你要测试的是你的数组是[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 。它理论上可以返回误报,但它是找出大多数错误的好方法。它基于以下事实:

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);
}

我不知道objective-c,但代码在C#中看起来像这样:

{{1}}

答案 2 :(得分:0)

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

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

         return YES;
    }

答案 3 :(得分:0)

这与你的itemsSequencedCorrectlyInSet:方法没什么不同,但是它使用了一个可变的索引集,它比执行更快 - [NSSet containsObject:]。在您拥有数千个表行之前,可能不是问题。无论如何,这里的关键见解是Pigeonhole原则说如果你有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;
}