也许使用一个NSCountedSet
(这相当于你可能用 实现的NSDictionary
)
-(NSArray*)renameStrings:(NSArray*)strings
{
NSCountedSet * set = [ [ NSCountedSet alloc ] initWithArray:strings ];
NSMutableArray * result = [ NSMutableArray arrayWithCapacity:[ strings count ] ] ;
for( id object in set )
{
NSUInteger count = [ set countForObject:object ] ;
if ( count == 1 )
{
[ result addObject:object ] ;
}
else
{
NSUInteger index= 0 ;
while( index < count )
{
++index ;
[ result addObject:[ NSString stringWithFormat:@"%@(%lu)", object, index ] ] ;
}
}
}
return result ;
}
(结果的排序可能与输入不同)
附录:
这是一个一次性解决方案,它也保持输入的顺序(只是为了“有趣”):
struct Tree
{
struct Tree * left ;
struct Tree * right ;
NSUInteger count ;
NSUInteger firstIndex ;
CFStringRef value ;
};
void TreeInsert( struct Tree * tree, NSMutableArray * resultArray, NSString * stringToInsert, NSUInteger stringIndex )
{
switch( CFStringCompare( (__bridge CFStringRef)stringToInsert , tree->value, 0 ) )
{
case NSOrderedAscending:
{
if ( tree->right )
{
TreeInsert( tree->right, resultArray, stringToInsert ,stringIndex ) ;
}
else
{
tree->right = malloc( sizeof( struct Tree ), 1 ) ;
*tree->right = (struct Tree){ NULL, NULL, 1, stringIndex, CFBridgingRetain( stringToInsert ) } ;
[ resultArray addObject:stringToInsert ] ;
}
break ;
}
case NSOrderedDescending:
{
if ( tree->left )
{
TreeInsert( tree->left, resultArray, stringToInsert ,stringIndex ) ;
}
else
{
tree->left = malloc( sizeof( struct Tree ), 1 ) ;
*tree->left = (struct Tree){ NULL, NULL, 1, stringIndex, CFBridgingRetain( stringToInsert ) } ;
[ resultArray addObject:stringToInsert ] ;
}
break ;
}
default:
{
++tree->count ;
if ( tree->firstIndex != NSNotFound )
{
NSString * string = [ NSString stringWithFormat:@"%@(1)", [ resultArray objectAtIndex:tree->firstIndex ] ] ;
[ resultArray replaceObjectAtIndex:tree->firstIndex withObject:string ] ;
tree->firstIndex = NSNotFound ;
}
[ resultArray addObject:[ NSString stringWithFormat:@"%@(%lu)", stringToInsert, tree->count ] ] ;
break ;
}
}
}
void DisposeTree( struct Tree * tree )
{
if ( tree->left ) { DisposeTree( tree->left ) ; }
if ( tree->right ) { DisposeTree( tree->right ) ; }
if ( tree->value ) { CFRelease( tree->value ) ; }
free( tree ) ;
}
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSArray * array = @[ @"Hello", @"Goodbye", @"Hello", @"Something else" ] ;
NSMutableArray * result = [ NSMutableArray arrayWithCapacity:array.count ] ;
struct Tree * tree = NULL ;
NSEnumerator * enumerator = [ array objectEnumerator ] ;
{
NSString * firstString = [ enumerator nextObject ] ;
tree = malloc( sizeof( struct Tree ), 1 ) ;
*tree = (struct Tree){ NULL, NULL, 1, 0, CFBridgingRetain( firstString ) } ;
[ result addObject:firstString ] ;
}
NSUInteger index = 1 ;
for( NSString * string in enumerator )
{
TreeInsert( tree, result, string, index ) ;
++index ;
}
NSLog(@"result=%@\n", result ) ;
}
}