比较字符串数组

时间:2016-01-27 01:21:24

标签: objective-c nsstring nsarray string-comparison

如果这是一个愚蠢的问题,请提前抱歉。我正在开发一个简单的程序来比较两个充满字符串的数组。一个是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中。因此,例如在控制台中,我将看到Woody和woody打印出来。

我尝试的另一种方式是:

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

当这样做时,它添加了names数组中的所有1309个字符串。在运行之前我实际上认为我不会得到任何匹配,因为我没有指定它不区分大小写。

我试图弄清楚为什么这些看起来如此相似的方法会产生不同的结果。我也试图找出为什么if ([[n lowerCaseString] compare:w] == NSEqualToComparison)是正确的方法。非常感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

使用时:

[[n lowercaseString] compare:w]

如果w为小写,则只会获得匹配。在您的不区分大小写的比较中,nw的大小写都会被忽略。这将解释不同的结果。 HTH

答案 1 :(得分: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。此外,不建议在此方案中使用快速迭代,因为如果阵列太大,性能可能会降低。

希望它能清除你的怀疑!