2016-01-27 287 views
0

對不起,如果這是一個愚蠢的問題。我正在研究一個簡單的程序,它比較兩個填充字符串的數組。一個是1309個專有名詞的清單,另一個是235,877個英語單詞的清單。程序的重點在於比較列表,並將出現在兩個列表上的任何單詞添加到可變數組中。然後,程序將枚舉可變數組並打印出兩個列表中的單詞。這裏是我的代碼:比較字符串數組

#import <Foundation/Foundation.h> 

int main(int argc, const char * argv[]) { 
    @autoreleasepool { 

     NSString *nameString = [NSString stringWithContentsOfFile:@"/usr/share/dict/propernames" 
            encoding:NSUTF8StringEncoding 
            error:NULL]; 
     NSString *wordString = [NSString stringWithContentsOfFile:@"/usr/share/dict/words" 
                 encoding:NSUTF8StringEncoding 
                  error:NULL]; 

     NSArray *names = [nameString componentsSeparatedByString:@"\n"]; 
     NSArray *words = [wordString componentsSeparatedByString:@"\n"]; 

     NSMutableArray *namesAndWords = [[NSMutableArray alloc]init]; 

     for (NSString *w in words){ 
      for (NSString *n in names){ 
       if ([[n lowercaseString] compare:w] == NSEqualToComparison){ 
        [namesAndWords addObject: w];}}} 

     for (NSString *item in namesAndWords){ 
      NSLog(@"%@", item);} 


     NSLog(@"There are %lu items in the array",[namesAndWords count]); 
     NSLog(@"%lu", [names count]); 
     NSLog(@"%lu", [words count]); 
    } 
    return 0; 
} 

至於現在,我已經有了這個計劃正是因爲它的工作應(顯示294場比賽)。我真正的問題是,當我第一次嘗試比較字符串我試着這樣說:

for (NSString *w in words){ 
      for (NSString *n in names){ 
       if ([n caseInsensitiveCompare:w] == NSEqualToComparison){ 
        [namesAndWords addObject: w];}}} 

像這樣:

for (NSString *w in words){ 
     for (NSString *n in names){ 
      if ([n compare:w options:NSCaseInsensitiveSearch] == NSOrderedSame){ 
       [namesAndWords addObject: w];}}} 

這兩種方式都送給我1602場比賽,由於某種原因增加了一些項目從兩個陣列到可變陣列namesAndWords。因此,例如在控制檯中,我會看到伍迪和木質的打印出來。

我嘗試另一種方法是這樣的:

for (NSString *w in words){ 
     for (NSString *n in names){ 
      if ([n compare:w] == NSOrderedSame){ 
       [namesAndWords addObject: w];}}} 

在做這種方式它添加了所有1309個字符串從names陣列。在運行之前,我實際上認爲我不會得到任何匹配,因爲我沒有指定它是不區分大小寫的。

我想弄清楚爲什麼這些看起來如此相似的方法有不同的結果,他們這樣做。我也試圖找出爲什麼if ([[n lowerCaseString] compare:w] == NSEqualToComparison)是正確的路要走。任何幫助在這裏非常感謝。

+0

不要使用'NSEqualToComparison',使用'NSOrderedSame'。查看顯示有效返回值的'compare:'方法的文檔。 – rmaddy

+1

你需要每個單詞的原始案例嗎?如果你用所有單詞的小寫版本創建兩個'NSSet'並且簡單地得到這兩個集合的交集,你可以使它更加高效。 – rmaddy

+0

是的,當找到一個匹配時,我希望'names'數組中的字符串是添加到'namesAndWords'可變數組中的字符串。這種方式當內容顯示在控制檯中時,它們就是正確的情況。 – JackLikesPizza

回答

0

因爲下面一行檢查字只轉換第一個數組的小寫字符串,而不是第二個字符串。它只獲得像m-> m這樣的匹配值,包括重複值。

[[n lowercaseString] compare:w] == NSEqualToComparison 

下面是我的鍛鍊爲您的問題。

NSMutableArray *actualarray1=[[NSMutableArray alloc] init]; 
NSMutableArray *actualarray2=[[NSMutableArray alloc] init]; 
actualarray1=[@[@"Apple",@"Litchi",@"Plum",@"Litchi",@"Pineapple",@"mango",@"Apple",@"berry",@"Pineapple",@"berry",@"mango",@"Apple"]mutableCopy]; 
actualarray2=[@[@"guava",@"Orange",@"Litchi",@"Pineapples",@"mangoes",@"Orange",@"Strawberry",@"Pineapple",@"berry",@"mango",@"Apple"]mutableCopy]; 
NSMutableArray *namesAndWords = [[NSMutableArray alloc]init]; 
for (NSString *w in actualarray1){ 
    for (NSString *n in actualarray2){ 
     if ([[n lowercaseString] compare:w] == NSEqualToComparison){ 
      [namesAndWords addObject: w];}}} 
NSLog(@"Array without duplicates %d",(int)[namesAndWords count]); 
namesAndWords=[[NSMutableArray alloc] init]; 
for (NSString *w in actualarray1){ 
    for (NSString *n in actualarray2){ 
     if ([n compare:w options:NSCaseInsensitiveSearch] == NSOrderedSame){ 
      [namesAndWords addObject: w];}}} 
NSLog(@"Array with duplicates %d",(int)[namesAndWords count]); 
namesAndWords=[[NSMutableArray alloc] init]; 
for (NSString *w in actualarray1){ 
    for (NSString *n in actualarray2){ 
     if ([n caseInsensitiveCompare:w] == NSOrderedSame){ 
      [namesAndWords addObject: w];}}} 
NSLog(@"Array with duplicates %d",(int)[namesAndWords count]); 

在上面的代碼中,數組1在其自身和數組2上也有重複。請嘗試一些手動迭代,只是因爲最後兩次比較最終會出現一對多映射。最後兩種在你的案例中產生重複的方法只是因爲你正在使用每個循環並檢查數組中的所有值。如果在比較之前刪除數組中的重複項,結果會是什麼?讓我們看看下面的代碼。

NSOrderedSet *orderedSet = [NSOrderedSet orderedSetWithArray:actualarray1]; 
     NSArray *arrayWithoutDuplicates = [orderedSet array]; 
     actualarray1=[arrayWithoutDuplicates mutableCopy]; 
     orderedSet = [NSOrderedSet orderedSetWithArray:actualarray2]; 
     arrayWithoutDuplicates = [orderedSet array]; 
     actualarray2=[arrayWithoutDuplicates mutableCopy]; 
     NSLog(@"%@ %@",actualarray1,actualarray2); 
     namesAndWords=[[NSMutableArray alloc] init]; 
     for (NSString *w in actualarray1){ 
      for (NSString *n in actualarray2){ 
       if ([n caseInsensitiveCompare:w] == NSOrderedSame){ 
        [namesAndWords addObject: w];}}} 
     //Your code works like a charm! 
     NSLog(@"After removing duplicates %d",(int)[namesAndWords count]); 


     namesAndWords=[[NSMutableArray alloc] init]; 
     for (NSString *s in actualarray1){ 
      if([actualarray2 containsObject:s]){ 
       [namesAndWords addObject: s]; 
      } 
     } 
     //This is my code which eventually reduces time 
     NSLog(@"Count after unique %d",(int)[namesAndWords count]); 

我建議你不要使用像[[n lowercaseString] compare:w] == NSEqualToComparison這樣的邏輯不正確的比較。因爲,您只將數組中的一個對象轉換爲小寫,而邏輯不正確。因爲它只能得到上面代碼中匹配的小寫數據。相反,如果在比較之前需要具有唯一值或刪除重複項的值,則可以使用[n caseInsensitiveCompare:w] == NSOrderedSame。另外,在這種情況下使用快速迭代不可取,因爲如果數組太大,性能可能會降低。

希望它清除你的懷疑!

0

當你使用:

[[n lowercaseString] compare:w] 

你只會得到一個匹配,如果w是小寫。在不區分大小寫的比較中,nw的情況都被忽略。這將解釋不同的結果。 HTH