输入一个字符串,打印出该字符串中字符的所有排列。
例如输入字符串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 ];
}
}