我有一个给定的矩阵(数组数组),如下所示:
NSArray *line1 = @[@"a1",@"b1",@"c1"];
NSArray *line2 = @[@"a2",@"b2",@"c2"];
NSArray *line3 = @[@"a3",@"b3",@"c3"];
NSArray *line4 = @[@"a4",@"b4",@"c4"];
NSArray *matrix = @[fret1,fret2,fret3];
定义的是,每一行的计数是相同的,但我不知道,每行有多少行和多少个条目。
我希望从每一行获得所有可能的值变化。
所以我有这个代码,它有效:
NSArray *line1 = @[@"a1",@"b1",@"c1"];
NSArray *line2 = @[@"a2",@"b2",@"c2"];
NSArray *line3 = @[@"a3",@"b3",@"c3"];
NSArray *line4 = @[@"a4",@"b4",@"c4"];
NSArray *matrix = @[line1,line2,line3,line4];
NSMutableArray *result = [NSMutableArray arrayWithCapacity:50];
NSInteger colCount = matrix.count;
NSInteger rowCount = [(NSArray*)[matrix objectAtIndex:0] count];
for (int lc1 = 0; lc1 < colCount; lc1++) {
for (int lc2 = 0; lc2 < colCount; lc2++) {
for (int lc3 = 0; lc3 < colCount; lc3++) {
NSString *row1 = [(NSArray*)[matrix objectAtIndex:lc1] objectAtIndex:0];
NSString *row2 = [(NSArray*)[matrix objectAtIndex:lc2] objectAtIndex:1];
NSString *row3 = [(NSArray*)[matrix objectAtIndex:lc3] objectAtIndex:2];
[result addObject:[NSString stringWithFormat:@"%@ %@ %@„,row1,row2,row3]];
}
}
}
for (int i = 0; i < result.count; i++) {
NSLog(@"%2ld: %@",(long)i,(NSString*)[result objectAtIndex:i]);
}
上面的代码给出了以下结果:
0: a1 b1 c1
1: a1 b1 c2
2: a1 b1 c3
3: a1 b1 c4
4: a1 b2 c1
5: a1 b2 c2
6: a1 b2 c3
7: a1 b2 c4
8: a1 b3 c1
9: a1 b3 c2
10: a1 b3 c3
11: a1 b3 c4
12: a1 b4 c1
13: a1 b4 c2
14: a1 b4 c3
15: a1 b4 c4
16: a2 b1 c1
17: a2 b1 c2
18: a2 b1 c3
19: a2 b1 c4
20: a2 b2 c1
21: a2 b2 c2
22: a2 b2 c3
23: a2 b2 c4
24: a2 b3 c1
25: a2 b3 c2
26: a2 b3 c3
27: a2 b3 c4
28: a2 b4 c1
29: a2 b4 c2
30: a2 b4 c3
31: a2 b4 c4
32: a3 b1 c1
33: a3 b1 c2
34: a3 b1 c3
35: a3 b1 c4
36: a3 b2 c1
37: a3 b2 c2
38: a3 b2 c3
39: a3 b2 c4
40: a3 b3 c1
41: a3 b3 c2
42: a3 b3 c3
43: a3 b3 c4
44: a3 b4 c1
45: a3 b4 c2
46: a3 b4 c3
47: a3 b4 c4
48: a4 b1 c1
49: a4 b1 c2
50: a4 b1 c3
51: a4 b1 c4
52: a4 b2 c1
53: a4 b2 c2
54: a4 b2 c3
55: a4 b2 c4
56: a4 b3 c1
57: a4 b3 c2
58: a4 b3 c3
59: a4 b3 c4
60: a4 b4 c1
61: a4 b4 c2
62: a4 b4 c3
63: a4 b4 c4
但是我怎么能动态地这样做,因为我不知道编译时我有多少行和列?
答案 0 :(得分:1)
首先定义一个函数,将矩阵的一列的所有元素追加到所有元素 以前获得的组合:
NSArray *combinations(NSArray *a, NSArray *matrix, NSUInteger column)
{
NSMutableArray *result = [NSMutableArray array];
for (NSString *elem in a) {
for (NSArray *row in matrix) {
NSString *tmp = [elem stringByAppendingFormat:@" %@", row[column]];
[result addObject:tmp];
}
}
return result;
}
然后以下给出想要的结果(适用于任意数字 行和列):
NSArray *line1 = @[@"a1",@"b1",@"c1"];
NSArray *line2 = @[@"a2",@"b2",@"c2"];
NSArray *line3 = @[@"a3",@"b3",@"c3"];
NSArray *line4 = @[@"a4",@"b4",@"c4"];
NSArray *matrix = @[line1,line2,line3,line4];
NSArray *result = @[@""];
for (NSUInteger column = 0; column < [line1 count]; column++) {
result = combinations(result, matrix, column);
}
for (NSUInteger i = 0; i < [result count]; i++) {
NSLog(@"%2lu: %@",(unsigned long)i,(NSString*)[result objectAtIndex:i]);
}
要了解其工作原理,让我们看看循环的每个步骤会发生什么。 在第一步中,列#0的所有元素都附加到空字符串:
0: a1 1: a2 2: a3 3: a4
在第二步中,列#1的所有元素都附加到来自的所有字符串 第一步:
0: a1 b1 1: a1 b2 2: a1 b3 3: a1 b4 4: a2 b1 5: a2 b2 6: a2 b3 7: a2 b4 8: a3 b1 9: a3 b2 10: a3 b3 11: a3 b4 12: a4 b1 13: a4 b2 14: a4 b3 15: a4 b4
在第三步中,第2列的所有元素都附加到所有字符串中 第二步:
0: a1 b1 c1 1: a1 b1 c2 2: a1 b1 c3 3: a1 b1 c4 4: a1 b2 c1 5: a1 b2 c2 6: a1 b2 c3 ... 58: a4 b3 c3 59: a4 b3 c4 60: a4 b4 c1 61: a4 b4 c2 62: a4 b4 c3 63: a4 b4 c4
在你的例子中有所有(有三列),但它的工作原理相同 列或行。
答案 1 :(得分:1)
@MartinR已经展示了一个很好的迭代解决方案,这里是一个递归的解决方案,为那些认为递归/只是为了好玩的人使用块: - ):
NSArray *line1 = @[@"a1",@"b1",@"c1"];
NSArray *line2 = @[@"a2",@"b2",@"c2"];
NSArray *line3 = @[@"a3",@"b3",@"c3"];
NSArray *line4 = @[@"a4",@"b4",@"c4"];
NSArray *matrix = @[line1,line2,line3,line4];
NSUInteger colCount = matrix.count;
NSUInteger rowCount = [matrix[0] count];
NSMutableArray *result = [NSMutableArray new];
NSMutableArray *sample = [NSMutableArray new];
__block __unsafe_unretained void (^weakCombinations)(NSUInteger);
void (^combinations)(NSUInteger);
weakCombinations = combinations = ^(NSUInteger row)
{
if (row == rowCount)
{
// have a complete sample
[result addObject:[sample componentsJoinedByString:@" "]];
}
else
{
// iterate over current column and recurse
for (NSUInteger ix = 0; ix < colCount; ix++)
{
sample[row] = matrix[ix][row];
weakCombinations(row+1);
}
}
};
combinations(0);
for (int i = 0; i < result.count; i++)
{
NSLog(@"%2ld: %@",(long)i,(NSString*)[result objectAtIndex:i]);
}
算法很简单,构建了通过矩阵的样本路径,当行到达路径时,用空格连接并添加到解集中。
注意:递归块过去不那么混乱,但在ARC下保留__block
变量,因此我们需要与weakCombinations
进行跳舞。 __unsafe_unretained
的使用在这里是安全的,并且比使用__weak
稍微有效一点,并且因为我们使用的块调用性能比方法更接近函数,为什么不多刮一点?