1

重複の可能性:
NSArray要素の順列の生成

私が持っているとしましょう

[1,2]

そして、私は取得したい

{1}
{2}
{1, 2}
{2, 3}
4

1 に答える 1

8

あなたが探しているものの名​​前は「パワーセット」だと思います。楽しそうだったので、ここでクラックします。アルゴリズムについては、この非常に簡潔な記事を参考にしました。これが大きなセットに対して効率的であるかどうかはわかりません (...実際には、これは非効率的であると確信しています)。

// answer the powerset of array: an array of all possible subarrays of the passed array
- (NSArray *)powerSet:(NSArray *)array {

    NSInteger length = array.count;
    if (length == 0) return [NSArray arrayWithObject:[NSArray array]];

    // get an object from the array and the array without that object
    id lastObject = [array lastObject];
    NSArray *arrayLessOne = [array subarrayWithRange:NSMakeRange(0,length-1)];

    // compute the powerset of the array without that object
    // recursion makes me happy
    NSArray *powerSetLessOne = [self powerSet:arrayLessOne];

    // powerset is the union of the powerSetLessOne and powerSetLessOne where
    // each element is unioned with the removed element
    NSMutableArray *powerset = [NSMutableArray arrayWithArray:powerSetLessOne];

    // add the removed object to every element of the recursive power set
    for (NSArray *lessOneElement in powerSetLessOne) {
        [powerset addObject:[lessOneElement arrayByAddingObject:lastObject]];
    }
    return [NSArray arrayWithArray:powerset];
}

これがキーパーだと思う場合は、配列のカテゴリ メソッドにして、パラメーターを削除できます。このようにテストしてください...

NSLog(@"empty = %@", [self powerSet:[NSArray array]]);
NSLog(@"one item = %@", [self powerSet:[NSArray arrayWithObject:@"a"]]);
NSLog(@"two items = %@", [self powerSet:[NSArray arrayWithObjects:@"a", @"b", nil]]);
NSLog(@"three items = %@", [self powerSet:[NSArray arrayWithObjects:@"a", @"b", @"c", nil]]);

これらのテストだけを行ったところ、出力は良好に見えました。ネタバレ注意: 3 つの項目のテストは、私のコンソールではおおよそ次のようになります (\n は削除されています)。

3つの項目 = ((), (a), (b), (a,b), (c), (a,c), (b,c), (a,b,c))

于 2012-11-30T03:43:57.443 に答える