生成所有可能的NSArray的最佳方法是什么,因为NSArray中只有2个可能的条目(X或Y)。在开始之前已经分配了数组中的某些值,并且无法更改。
例如,此处的数组具有16种可能的排列,使得位置1和2已经锁定到X& Y分别不能改变。位置0可以采用X或Y,但不能为空。像明智的职位3,4,5。
0:[ ]
1:[X]
2:[Y]
3:[ ]
4:[ ]
5:[ ]
[]表示没有分配给数组中该位置的任何内容,因此在计算所有排列时需要分配X或Y.它是单维数组或大小6。 我在Objective-C中为iOS设备编码。这里的任何指导将不胜感激。
谢谢 - C
答案 0 :(得分:0)
我想我明白你的目的:产生从一组长度为2(@“X”和“Y”)中选出的6个对象的排列,排除那些具有给定模式的对象。
这里有一个很好的速度/空间权衡,因为从一组长度2中选择的6个对象只有64个排列。整个集合足够小,可以提前计算并保存在手边。有了这个,算法就变成了对“固定”位置模式的简单过滤。
我们需要一种方法来表示这种模式。 NSArrays不像C数组那样定位。计数数组6必须在每个索引1..5处包含一个对象,因此一个简单的方法是选择另一个对象来表示“未固定”位置,(OP相当于“[]”)。例如,如果我们使用@"*"
,(NSNull
个实例也是一个不错的选择),OP排除的模式看起来就像这个文字:
@[ @"*", @"X", @"Y", @"*", @"*", @"*" ]
让我们从完整的排列开始。懒惰地计算这些(在第一次调用时计算和缓存,然后返回缓存的结果):
@property(strong,nonatomic) NSArray *permutations;
- (NSArray *)permutations {
if (!_permutations) {
NSSet *set = [NSSet setWithArray:@[ @"X", @"Y"]];
_permutations = [self permute:set count:6];
}
return _permutations;
}
// simple recursive algorithm to permute
- (NSArray *)permute:(NSSet *)set count:(NSInteger)count {
NSMutableArray *result = [@[] mutableCopy];
if (count == 1) {
for (id object in [set allObjects]) [result addObject:@[object]];
return result;
} else {
NSArray *smaller = [self permute:set count:count-1];
for (id object in [set allObjects]) {
for (NSArray *array in smaller) {
NSMutableArray *m = [array mutableCopy];
[m insertObject:object atIndex:0];
[result addObject:m];
}
}
return result;
}
}
这将产生类似......的排列。
@[ @[ @"X", @"X", @"X", @"X", @"X", @"X" ],
@[ @"X", @"X", @"X", @"X", @"X", @"Y" ], // ... and so on
您甚至可以在编译时执行此操作,并将该结果作为64元素数组文字包含在您的应用中。
有了这个,问题就变成了过滤器。这是测试给定数组是否匹配模式(使用@“*”作为外卡)的测试:
- (BOOL)array:(NSArray *)array matchesPattern:(NSArray *)pattern {
for (NSInteger i=0; i<array.count; i++) {
if (![pattern[i] isEqualToString:@"*"] && ![array[i] isEqualToString:pattern[i]]) return NO;
}
return YES;
}
将该过滤器应用为谓词:
NSArray *pattern =@[ @"*", @"X", @"Y", @"*", @"*", @"*" ];
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary * bindings) {
NSArray *a = (NSArray *)evaluatedObject;
return [self array:a matchesPattern:pattern];
}];
并进行过滤:
NSArray *permutations = [self permutations];
NSArray *result = [permutations filteredArrayUsingPredicate:predicate];
我用OP参数和一些变化进行了测试。