比较字符串数组

Comparing string arrays

如果这是一个愚蠢的问题,请提前道歉。我正在开发一个简单的程序来比较两个充满字符串的数组。一个是包含 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) 是正确的方法。非常感谢这里的任何帮助。

当您使用时:

[[n lowercaseString] compare:w]

只有当 w 是小写时,您才会得到匹配。在不区分大小写的比较中, nw 的大小写都被忽略。这将解释不同的结果。 HTH

因为下行检查单词只转换第一个数组的小写字符串而不是第二个数组。它只获得像 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 都有重复项。请尝试一些手动迭代,这只是因为最后两次比较以 one-to-many 映射结束。在您的案例中产生重复项的最后两种方法只是因为您正在使用每个循环并检查数组中的所有值。如果在比较之前删除数组中的重复项,结果会怎样?让我们看看下面的代码。

 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。此外,在这种情况下不建议使用快速迭代,因为如果数组太大,性能可能会下降。

希望它能消除您的疑虑!