我有以下问题:我有一个整数数组,我想将它们放在一个数据结构中,每个整数都包含其出现次数,然后按出现次数排序。
所以,如果我有:
[1, 3, 4, 6, 6, 3, 1, 3]
我会:
[(4,1), (6,2), (1,2), (3,3)]
其中(x,y)==(整数,其出现次数)。
我尝试使用NSCountedSet,但效果不好,我想知道最好的方法是什么。
到目前为止,我已完成以下工作:
NSCountedSet *totalSet = [[NSCountedSet alloc] initWithArray:finalArray];
其中finalArray是完整原始数据未排序的最终数组。 totalSet分为(x,y)但未排序(理想情况下,应按'y'排序)。
我也试过这样做,但它不起作用:
NSArray *sortedArray = [finalArray sortedArrayUsingSelector:@selector(compare:)];
然后做:
NSCountedSet *totalSet = [[NSCountedSet alloc] initWithArray:finalArray];
但这并没有改变'totalSet'。
答案 0 :(得分:4)
首先,让我们定义一个方便的元组类型,我们可以用它来将数字与其出现次数相关联:
@interface Pair : NSObject
@property(nonatomic, strong) id key;
@property(nonatomic, strong) id value;
- (id)initWithKey:(id)key value:(id)value;
@end
@implementation Pair
- (id)initWithKey:(id)key value:(id)value;
{
if((self = [super init])) {
_key = key;
_value = value;
}
return self;
}
- (NSString *)description
{
return [NSString stringWithFormat:@"(%@,%@)", self.key, self.value];
}
@end
然后,要获得所需的结果,请使用计数集来计算出现次数,然后将结果填充到元组数组中,并按出现次数排序。
- (void)testOccurrenceCounting
{
NSArray *numbers = @[@1, @3, @4, @6, @6, @3, @1, @3];
NSCountedSet *set = [[NSCountedSet alloc] initWithArray:numbers];
NSMutableArray *counters = [NSMutableArray arrayWithCapacity:[set count]];
[set enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
[counters addObject:[[Pair alloc] initWithKey:obj value:@([set countForObject:obj])]];
}];
[counters sortUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"value" ascending:YES]]];
NSLog(@"%@", counters);
}
counters
现在是Pair
个对象的排序数组,其中key
属性包含数字,value
属性包含出现次数,两者都装箱为NSNumbers
。从那里,您可以取消装箱或根据需要操纵集合。
作为证明这是有效的,这是NSLog
陈述的输出:
(
"(4,1)",
"(6,2)",
"(1,2)",
"(3,3)"
)
答案 1 :(得分:3)
您可以将数字及其计数放入字典数组中,如下所示:
NSArray *arr = @[@1, @3, @4, @6, @6, @3, @1, @3];
NSCountedSet *totalSet = [NSCountedSet setWithArray:arr];
NSMutableArray *dictArray = [NSMutableArray array];
for (NSNumber *num in totalSet) {
NSDictionary *dict = @{@"number":num, @"count":@([totalSet countForObject:num])};
[dictArray addObject:dict];
}
NSArray *final = [dictArray sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"number" ascending:YES ]]];
NSLog(@"%@",final);
答案 2 :(得分:2)
这是我的答案版本。如果您不想使用自定义类,并希望将它们作为单独的数组排序,按照其出现次数的顺序排序,您可以尝试这样做。
创建一个这样的函数,
NSInteger countedSort(id obj1, id obj2, void *context) {
NSCountedSet *countedSet = (__bridge NSCountedSet *)(context);
NSUInteger obj1Count = [countedSet countForObject:obj1];
NSUInteger obj2Count = [countedSet countForObject:obj2];
if (obj1Count < obj2Count) return NSOrderedAscending;
else if (obj1Count > obj2Count) return NSOrderedDescending;
return NSOrderedSame;
}
并使用此,
NSArray *finalArray = @[@1, @3, @4, @6, @6, @3, @1, @3];
NSCountedSet *totalSet = [[NSCountedSet alloc] initWithArray:finalArray];
NSArray *sortedBasedOnCountArray = [[totalSet allObjects] sortedArrayUsingFunction:countedSort context:(__bridge void *)(totalSet)];
NSLog(@"sortedObjectsBasedOnCountArray = %@", sortedBasedOnCountArray);
NSMutableArray *countArray = [NSMutableArray arrayWithCapacity:[sortedBasedOnCountArray count]];
for (id object in sortedBasedOnCountArray) {
[countArray addObject:[NSNumber numberWithInt:[totalSet countForObject:object]]];
}
NSLog(@"countArray = %@", countArray);
<强>输出:强>
sortedObjectsBasedOnCountArray = (
4,
6,
1,
3
)
countArray = (
1,
2,
2,
3
)
请注意,两个数组按相同顺序排序,数组索引可用于链接它们。
同时检查此NSBag实施。