2012-01-01 3 views
6

고유 한 문자 집합을 가진 문자열 만 추출하려는 문자열 배열이 있습니다. 예를 들어 "asdf"및 "fdsa"는 중복으로 간주됩니다. 현재 사용중인 방법입니다.Objective-C에서 같은 문자가있는 문자열을 확인하십시오.

NSMutableArray *uniqueCharSets = [[NSMutableArray alloc] init]; 
NSMutableArray *uniqueStrings = [[NSMutableArray alloc] init];   

for (NSString *_string in unique) { 
    NSCharacterSet *_charSet = [NSCharacterSet characterSetWithCharactersInString:_string]; 
    if (![uniqueCharSets containsObject:_charSet]) { 
     [uniqueStrings addobject:_string]; 
     [uniqueCharSets addObject:_charSet]; 
    } 
} 

이 방법은 효과가있는 것으로 보이지만 속도가 매우 느리고 리소스가 많이 소요됩니다. 누구든지 이것을 할 수있는 더 좋은 방법을 생각할 수 있습니까?

+0

귀하의 사양에 따라 'asdf'와 'asdfg'가 고유합니까? –

+0

네, 그것들은 유일 할 것입니다. – Rob

답변

0

나는 이것에 어떻게 접근 할 것인가에 대한 빠른 예를 하나 넣었지만, 처음에는 기대했던 것보다 더 이상하다고 밝혀졌습니다. 하나의 경우, NSCharacterSet은 내용을 검사하는 동등성을 구현하지 않습니다. 포인터 값만 사용합니다. 이 예제를 기반으로 제대로 작동하지 않습니다.

내 접근 방식은 NSSet을 사용하여 이들에 대한 해싱을 처리하는 것입니다.

@interface StringWrapper : NSObject 
@property (nonatomic, copy) NSString *string; 
@property (nonatomic, copy) NSData *charSetBitmap; 
- (id)initWithString:(NSString*)aString; 
@end 

@implementation StringWrapper 
@synthesize string, charSetBitmap; 

- (id)initWithString:(NSString*)aString; 
{ 
    if ((self = [super init])) 
    { 
     self.string = aString; 
    } 
    return self; 
} 

- (void)setString:(NSString *)aString; 
{ 
    string = [aString copy]; 
    self.charSetBitmap = [[NSCharacterSet characterSetWithCharactersInString:aString] bitmapRepresentation]; 
} 

- (BOOL)isEqual:(id)object; 
{ 
    return [self.charSetBitmap isEqual:[object charSetBitmap]]; 
} 

- (NSUInteger)hash; 
{ 
    return [self.charSetBitmap hash]; 
} 

@end 

int main (int argc, const char * argv[]) 
{ 
    @autoreleasepool { 
     NSMutableSet *stringWrappers = [[NSMutableSet alloc] init]; 
     NSArray *strings = [NSArray arrayWithObjects:@"abc",@"aaabcccc",@"awea",@"awer",@"abcde", @"ehra", @"QWEQ", @"werawe", nil]; 
     for (NSString *str in strings) 
      [stringWrappers addObject:[[StringWrapper alloc] initWithString:str]]; 

     NSArray *uniqueStrings = [stringWrappers valueForKey:@"string"]; 
     NSLog(@"%@", uniqueStrings); 

    } 
    return 0; 
} 

코드는 매우 간단합니다. 우리는 문자 세트의 비트 맵 표현 결과를 캐시하기위한 컨테이너 객체를 생성합니다. NSDataisEqual:을 적절히 구현하므로 비트 맵 표현을 사용합니다. 내 마음에 와서

0

유일한 것은 containsObject를 사용하지 않는 것입니다 : NSMutableArray는 (일반적으로) 정렬되지 않기 때문에, 우리는 containsObject 단순히 그 객체를 찾을 때까지 처음부터 시작하는 배열을 반복 할 것으로 가정 할 수있다. 이는 O(n) (최악의 경우 n 개 비교)을 의미합니다.

더 나은 해결책은 배열을 정렬 된 상태로 유지하고 dichotomic approach을 사용하는 사용자 지정 검색 방법을 사용하는 것입니다. 이렇게하면 O(log n)의 복잡성을 갖게됩니다.
물론 배열을 유지 관리해야합니다 (추가 및 순서 재 지정보다 훨씬 효율적입니다). 따라서 요소를 올바르게 삽입하려면 insertObject:atIndex: 메소드를 사용해야합니다.

1
  1. 입력 문자열의 NSArray 각 스트링의 사전 식 분류 된 등가 맵핑 NSDictionary 사용 (예 adfs =>[afsd, asdf, ...]) 사전 통해
  2. 걷기 만이 키 (또는 값)를 프린트 단일 요소 배열 값
관련 문제