Objective c 所有可能的组合,无需从NSArray重复

Objective c 所有可能的组合,无需从NSArray重复,objective-c,math,nsarray,combinatorics,Objective C,Math,Nsarray,Combinatorics,假设我有一个包含3个数字的数组: NSArray *array = @[@1, @2, @3]; 我希望所有的组合都不重复。 所以我需要的是: (1) (2) (3) (1,2) (2,3) (1,3) (1、2、3) 我目前拥有的代码如下: NSArray *array = @[@1, @2, @3]; int numberOfCardsOTable = [array count]; //NSLog(@"array = %@", array); for (int lenghtOfArra

假设我有一个包含3个数字的数组:

NSArray *array = @[@1, @2, @3];
我希望所有的组合都不重复。
所以我需要的是:
(1)
(2)
(3)
(1,2)
(2,3)
(1,3)
(1、2、3)

我目前拥有的代码如下:

NSArray *array = @[@1, @2, @3];
int numberOfCardsOTable = [array count];

//NSLog(@"array = %@", array);

for (int lenghtOfArray = 1; lenghtOfArray <= numberOfCardsOTable; lenghtOfArray++)
{
    for (int i = 0; i < numberOfCardsOTable; i++)
    {
        // array bound check
        if (i + lenghtOfArray > numberOfCardsOTable) {
            continue;
        }

        NSArray *subArray = [[NSMutableArray alloc] init];

        subArray = [array subarrayWithRange:NSMakeRange(i, lenghtOfArray)];

        NSLog(@"array = %@", subArray);
    }
}
NSArray*array=@[@1、@2、@3];
int numberOfCardsOTable=[数组计数];
//NSLog(@“数组=%@”,数组);
对于(int lenghtOfArray=1;lenghtOfArray numberOfCardsOTable){
继续;
}
NSArray*子阵列=[[NSMutableArray alloc]init];
子阵列=[阵列子阵列WithRange:NSMakeRange(i,lenghtOfArray)];
NSLog(@“数组=%@”,子数组);
}
}
但是这个代码丢失了(1,3)

我需要对长度最多为8个数字的源阵列执行此操作。

对于8个数字,有255个组合,我的算法将丢失很多,因此如果s,则会丢失大量的

范围将永远不适用于此场景

有趣的是,你可能想考虑以下内容:

NSArray *array = @[@1, @2, @3];
//NSArray *array = @[@1, @2, @3, @4];
int numberOfCardsOTable = [array count];

//this can be calculated too - a row in Pascal's triangle
NSArray *pascalsRow = @[@1, @3, @3, @1];
//NSArray *pascalsRow = @[@1, @4, @6, @4, @1];

int pIndex = 1;
int endIdx = [[pascalsRow objectAtIndex:pIndex] integerValue];
int outputLength;

//process the number of expected terms in pascal row
for (int i = 0; i < [pascalsRow count]; i++)
{
    //skipping first term
    outputLength = i;
    if(outputLength > 0)
    {
        for (int j = i; j <= endIdx; j++)
        {
            if(outputLength > 1)
            {
                for(int k = 1; k <= endIdx; k++)
                {
                    NSLog(@"j = %i, k = %i, ... outputLength = %i", j, k, outputLength);
                }
                j = endIdx;
            }
            else
                NSLog(@"j = %i, ... outputLength = %i", j, outputLength);
        }

        if(pIndex < numberOfCardsOTable)
        {
            pIndex++;
            NSLog(@"pIndex = %i, endIdx = %i", pIndex, endIdx);
            endIdx = [[pascalsRow objectAtIndex:pIndex] integerValue];
        }

        if(endIdx == 1 && outputLength == numberOfCardsOTable)
            NSLog(@"... outputLength = %i", outputLength);
    }
}

由于您似乎希望组合的顺序与原始集合的顺序相同,因此您所做的操作与计算2num_选项并选择与集合位对应的对象相同。通过我为
NSIndexSet
编写的一个category方法,您可以非常轻松地完成这项工作

@implementation NSIndexSet (WSSNoncontiguous)

+ (instancetype)WSSIndexSetFromMask:(uint64_t)mask
{
    NSMutableIndexSet * set = [NSMutableIndexSet indexSet];

    for( uint64_t i = 0; i < 64; i++ ){
        if( mask & (1ull << i) ){
            [set addIndex:i];
        }
    }

    return set;
}

@end

显然,这只适用于拥有64个或更少成员的
选项
,但无论如何,这将导致大量组合。

谢谢您的评论。我还没有测试过。我接受了Josh的答案,因为代码更小。64个选项有1.8*10**19个组合,即18个五分之一。我需要它8(理论上最大51),所以这对我是好的。
@implementation NSIndexSet (WSSNoncontiguous)

+ (instancetype)WSSIndexSetFromMask:(uint64_t)mask
{
    NSMutableIndexSet * set = [NSMutableIndexSet indexSet];

    for( uint64_t i = 0; i < 64; i++ ){
        if( mask & (1ull << i) ){
            [set addIndex:i];
        }
    }

    return set;
}

@end
NSArray * choices = @[...];
uint64_t num_combos = 1ull << [choices count];    // 2**count
NSMutableArray * combos = [NSMutableArray new];
for( uint64_t i = 1; i < num_combos; i++ ){
    NSIndexSet * indexes = [NSIndexSet WSSIndexSetFromMask:i];
    [combos addObject:[choices objectsAtIndexes:indexes]];
}