2012-12-14 95 views
1

我有以下問題:我有一個整數數組,我想把它們放在一個數據結構中,每個整數都有其出現的數字,然後按數字排序的事件。用計數索引對數組進行排序

所以,如果我有:

[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

你想要什麼結果的結構是什麼?字典數組是否正確? – rdelmar

+0

結果應該是按'y'排序的一系列(x,y)。 – moshikafya

回答

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); 
+0

花了3個小時試圖弄清楚這一點,謝謝你的回答! –

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)" 
) 
+0

好的答案....! – TheTiger

+0

美女。很好的答案。 – nithinbhaktha

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實施。