题目:集合求全子集

例如:
{123} -> { {}, {1}, {2}, {3}, {1,2}, {1,3}, {2,3}, {1,2,3} }

参考:http://www.mamicode.com/info-detail-1269237.html

解法一:二进制法

- (void)viewDidLoad {
    [super viewDidLoad];
   
    [self p_allSubSet];
}

- (void)p_allSubSet {    
    NSArray *arr = @[@"a", @"b", @"c"];
    NSSet *input = [NSSet setWithArray:arr];
    NSSet *result = [self wholeSubSet:input];
    NSLog(@"input set: %@, all subset result: %@", input, result);
}

//集合的全子集 数量肯定是 2的n次方(n为集合中元素的数量)
//转换成一个二进制亮灯模型,一个灯可以点亮或者熄灭(对应是否选到集合中)
- (NSMutableSet *)wholeSubSet:(NSSet *)input {
    NSInteger n = [input count];
    NSMutableSet *result = [NSMutableSet set];

    for (int i = 0;i <= pow(2, n) - 1;i++) {
        NSMutableSet *inputM = [input mutableCopy];
        __block NSInteger index = 0;
        [input enumerateObjectsUsingBlock:^(id  _Nonnull obj, BOOL * _Nonnull stop) {
            if ([self lightUp:i atIndex:index]) {
                //do nothing
            } else {
                [inputM removeObject:obj];
            }
            index++;
        }];
        [result addObject:inputM];
    }
    return result;
    /*
     时间复杂度:O(n*2^n)。
     空间复杂度为O(n)。
     */
}

///> 判断对应位置的灯泡是否可以点亮
- (BOOL)lightUp:(NSInteger)i atIndex:(NSInteger)index {
    //i = 1(001)
    NSInteger bit = pow(2,index);//(index 0, 001; 1, 010; 2 100)
    if (i & bit) {//与 都为1 才为1
        return YES;
    } else {
        return NO;
    }
}

解法二:递归法

- (NSMutableSet *)wholeSubSet2:(NSSet *)input {
    /*
     设。原始集合s=<a,b,c,d>,子集结果为r:
     第一次迭代: r=<a> 第二次迭代:r=<a ab b>
     第三次迭代: r=<a ab b ac abc bc c>
     第四次迭代:r=<a ab b ac abc bc c ad abd bd acd abcd bcd cd d>
     */
    NSMutableSet *result = [NSMutableSet set];
    NSInteger index = 0;
    for (NSString *str in input) {
        if (index == 0) {
            NSMutableSet *aSet = [NSMutableSet set];
            [aSet addObject:str];
            [result addObject:aSet];
        } else {
            //上次的结果result + 上次的结果join这次的元素(joinSet:obj:) + 这次的元素str
            NSSet *combinedSet = [self joinSet:result obj:str];
            for (NSSet *cSet in combinedSet) {
                [result addObject:cSet];
            }
            NSMutableSet *aSet = [NSMutableSet set];
            [aSet addObject:str];
            [result addObject:aSet];//这次的元素
        }
        index++;
    }
    NSSet *emptySet = [NSSet set];
    [result addObject:emptySet];
    return result;
}

- (NSMutableSet<NSSet *> *)joinSet:(NSSet <NSSet *>*)set obj:(NSString *)str {
    NSMutableSet *result = [NSMutableSet set];
    for (NSSet *theSet in set) {
        NSMutableSet *setM = [NSMutableSet setWithSet:theSet];
        [setM addObject:str];
        [result addObject:setM];
    }
    return result;
}