枚举字符串的排列, 八皇后,枚举&回溯2种解法

输入一个字符串,打印出该字符串中字符的所有排列。
例如输入字符串abc,则打印出由字符a、b、c所能排列出来的所有字符串abc, acb , bac、bca, cab cba。


由于字符串的长度不同, 使用for循环嵌套枚举是不行的, 需要使用递归才能处理不定长度的字符串.

需要把字符全排列, 每个字符都可能出现在第一位置, 可以看成  完整字符 =  单个字符 + 剩余字符的全排列 , 剩余字符的全排列 = 单个字符 + (剩余字符-单个字符)的全排列, 这样下去,剩余字符会越来越少, 当剩余字符没有时, 说明全排列已经完成了.
现在说一个例子 ,
ABCD的全排列 = A + BCD的全排列;  ABCD的全排列 = B + ACD的全排列;   ABCD的全排列 = C + ABD的全排列;   ABCD的全排列 = D + ABC的全排列;  
BCD的全排列 = B + CD的全排列;   BCD的全排列 = C + BD的全排列;  BCD的全排列 = D + BC的全排列; 
CD的全排列 = C + D;  CD的全排列 = D + C ;

经过这样分解子问题 , 就可以写出递归的代码了.

- (void)viewDidLoad {
    [super viewDidLoad];

    [self logAllString];
    
}

// 枚举字符串的所有组合
- (void)logAllString {
    
    NSString * str = @"ABCD";
    
    // 把str的每个字符加入到数组中
    NSMutableArray<NSString *> * array = [NSMutableArray arrayWithCapacity:str.length];
    for (int i = 0; i<str.length; i++) {
        [array addObject:[str substringWithRange:NSMakeRange(i, 1)]];
    }
    [self __logString:@"" withLeftArray:array];
    
}
/// 每次都是 原始字符串+剩下的没有处理的数组
- (void)__logString:(NSString *)str withLeftArray:(NSMutableArray *)leftArray{
    
    if (leftArray.count==0) {
        static int count = 1;
        NSLog(@"%@  第%d种",str,count++);
        return;
    }

    for (NSString * oneChar in leftArray) {
        // 从剩余的数组中移除本次添加的oneChar
        NSMutableArray * copyArray = [leftArray mutableCopy];
        NSString * result = [NSString stringWithFormat:@"%@%@",str,oneChar];
        [copyArray removeObject:oneChar];
        [self __logString:result withLeftArray:copyArray ];

    }
    
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章