2012-03-25 15 views
1

私は整数の配列を維持しています。この配列の整数は常に0から順になることが重要です。たとえば、配列に5つの整数がある場合、その値は0,1,2,3,4(いずれの順序であっても)でなければなりません。一貫性のために一連の数値を調べる

これを確認する簡単で効率的な方法を設計したいと思います。配列に0からarray.count - 1の順番ですべての正の整数が含まれている場合は、trueを返します。

これを処理するためのいくつかの異なるアイデアをお聞きしたいと思います。

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

     return YES; 
    } 
+0

*確実にする必要がある場合は、配列内の各要素を調べてチェックするよりもうまくいくことはできません。したがって、配列の長さから1を引いたものを0から数え、配列の位置iにあるものが実際には値iであることを確認してください。 (唯一の「最適化」は、カウントを続けるのではなく、何かでなければならない要素に遭遇するたびにfalseを返すことです)。編集:ああ、マティアスは良い点を作っています:とにかくこの配列を保持するのは何ですか?あなたは 'n '以下のすべての自然数をどのように計算するのかよく知っています。 – gspr

+0

何のために配列を使用していますか?配列の上限を維持し、整数を反復する方が簡単ではないでしょうか? – Mathias

+0

私は、配列を使用してテーブルビューを設定します。数字はソート順です。私はアイテムをさまざまな方法でセクション内にドロップします。ソート順を正しく設定するメソッドが必要なので、アイテムをセクションの内外に移動した後、ギャップなどはありません。私が現在やっていること - あなたの提案に合っていると思います。私は数を合計し、フィボナッチシーケンスと比較することを見ていました - おそらく効率的ではありませんが、楽しいかもしれません)。 –

答えて

0

これはあなたのitemsSequencedCorrectlyInSetからあまり違いはありません:メソッドではなく、[NSSet containsObject:]を実行するよりも速い可変インデックスセットを使用します。あなたが何千ものテーブル行を取得するまで、おそらく問題はありません。とにかく、ここでの重要な洞察は、ピジョンホールの原理は、N以下の整数がN未満であり、重複がない場合、0 ... N-1のそれぞれを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; 
} 
+0

私は私の質問で「効率的」と言いましたが、これは最も実用的なようです。ありがとう! –

0

ここに私の現在の実装では、(TESTSETはNSNumbersのセットです)です。これは、N個の整数の他の集合が持つプロパティではありません。

私はこれを代替案として提供していますが、これは適合性、性能、効率性についての主張をしていません。Nが大きくなるにつれて問題が生じることを認識しています。

3

それとも、あなたは順番に各のパワーに2を上げると、整数[0..N-1]与えられた合計は-1+2^Nになります -

+0

これは精神です - いかがですか、ありがとう:) –

+0

@GregS:そうです!そして、私は不器用な答えを修正しました。 –

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 

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