2012-01-01 3 views
6

में समान वर्णों के लिए तारों की जांच करें मेरे पास तारों की एक सरणी है, जिसमें से मैं केवल अद्वितीय वर्ण सेट वाले लोगों को निकालना चाहता हूं। (उदाहरण के लिए, "asdf" और "fdsa" को अनावश्यक माना जाएगा)। यह वह तरीका है जिसका मैं वर्तमान में उपयोग कर रहा हूं:उद्देश्य-सी

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

आपके spec के अनुसार 'asdf' और 'asdfg' अद्वितीय हैं? –

+0

हां, वे अद्वितीय होंगे। – Rob

उत्तर

0

मैंने अभी एक त्वरित उदाहरण दिया है कि मैं इस पर कैसे पहुंचूंगा, लेकिन यह पता चला है कि यह पहले की तुलना में अधिक अजीब है। एक के लिए, NSCharacterSet सामग्री की जांच के लिए समानता लागू नहीं करता है। यह केवल सूचक मूल्य का उपयोग करता है। इस पर आधारित आपका उदाहरण ठीक से काम नहीं करेगा।

मेरा दृष्टिकोण हमारे लिए इन्हें हैशिंग से निपटने के लिए एनएसएससेट का उपयोग करना है।

@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; 
} 

कोड बहुत सरल है। हम चरित्र सेट के बिटमैप प्रतिनिधित्व के परिणामों को कैश करने के लिए एक कंटेनर ऑब्जेक्ट बनाते हैं। हम बिटमैप प्रतिनिधित्व का उपयोग करते हैं क्योंकि NSData लागू isEqual: लागू करता है।

0

केवल बात यह है कि मेरे मन में आ containsObject उपयोग करने के लिए नहीं है: के बाद से NSMutableArray (सामान्य रूप में) का आदेश दिया है, हम मान सकते हैं कि containsObject बस सरणी प्रारंभ से लेकर जब तक वह वस्तु पाता iterates। इसका मतलब है O(n) (n सबसे खराब मामले में तुलना)।

एक बेहतर समाधान में सरणी को व्यवस्थित रखने और dichotomic approach का उपयोग करके एक कस्टम खोज विधि का उपयोग करने में शामिल हो सकता है। इस तरह आपके पास O(log n) जटिलता होगी।
बेशक, आपको अपने सरणी को आदेश देने (जोड़ने और पुन: व्यवस्थित करने से अधिक कुशल) रखने का ख्याल रखना चाहिए, इसलिए आपको तत्व को ठीक से सम्मिलित करने के लिए insertObject:atIndex: विधि का उपयोग करना चाहिए।

1
  1. एक NSDictionary का उपयोग करना, इनपुट तार का एक NSArray करने के लिए प्रत्येक स्ट्रिंग के कोषगत-अनुसार क्रमबद्ध बराबर नक्शा: (जैसे adfs =>[afsd, asdf, ...])
  2. शब्दकोश के माध्यम से वॉक, कुंजी (या उनके मान) जो केवल प्रिंट एकल-तत्व सरणी मान