【问题标题】:Get matched string from two NSArrays从两个 NSArray 中获取匹配的字符串
【发布时间】:2011-08-25 17:40:14
【问题描述】:

如何保存与NSArray 匹配的字符串,而NSMutableArray 中有一个索引差异?

例如,nsarray 中有 3 个“apple”,4 个“pineapple”,6 个“banana”,2 个“cocoa”,其余单词没有重复,我想知道 nsarray至少有两个相同的词。如果是,我想在 nsmutablearray 中保存一次“apple”、“pineapple”、“banana”和“cocoa”。如果有其他类似的词,我也想将它们添加到 namutablearray 中。

我的代码(仍然不能正常工作);

NSArray *noWords = [[NSArray alloc] initWithArray:
                          [[NSString stringWithContentsOfFile:[[NSBundle mainBundle] 
                             pathForResource:@"words" ofType:@"txt"]                                               
                             encoding:NSUTF8StringEncoding error:NULL] 
                            componentsSeparatedByString:@"\n"]];

NSUInteger scount = [noWords count];
int ii = 0;
NSString *stringline;
for (ii; ii < scount; ii++)
{
    stringline = [noWords objectAtIndex:ii];
    NSLog(@"stringline : %@ ", stringline);
}
int i = 1;
NSString *line;
for (i ; i < 10; i++)
{
    line = [noWords objectAtIndex:i];
    NSLog (@"line : %@ ", line);

    NSMutableArray *douwords = [NSMutableArray array];

    if ([stringline isEqualToString:line])
    {
        NSString *newword;
        for (newword in douwords)
        {
            [douwords addObject:newword]; 
            NSLog (@"detected! %@ ", douwords);
        }
    }
}

【问题讨论】:

  • 您可能需要重新表述您的问题,因为它根本不清楚您要完成什么。
  • 您是否尝试将一个数组中具有重复项的所有字符串添加到另一个数组中?
  • @matt 正确!对不起,我的英语不好。

标签: objective-c nsstring nsarray


【解决方案1】:

这是使用两组的解决方案:

- (NSArray *)getDuplicates:(NSArray *)words
{
    NSMutableSet *dups = [NSMutableSet set],
                 *seen = [NSMutableSet set];

    for (NSString *word in words) {
        if ([seen containsObject:word]) {
            [dups addObject:word];
        }
        [seen addObject:word];
    }

    return [dups allObjects];
}

假设 NSSet 在幕后使用哈希表(我打赌确实如此),这将比之前建议的 O(n^2) 解决方案更快。

【讨论】:

  • @cameron 这对其他回答的人不公平,尤其是先回答的马特,所以我只是投票给你们。
  • 随便选一个你喜欢的答案。如果您不选择答案,则问题将一直悬而未决,并且人们将永远回到该问题以回答它。我认为 Matt 和 Cameron 可以牺牲公平性来拯救成群的开发人员打开已经回答的问题。
  • @niels 我明白了。谢谢你告诉我。所有答案都很好,但我接受了你的答案,因为你的答案更详细、更深入。
【解决方案2】:

这是我的想法:

NSMutableSet* duplicates = [NSMutableSet set];
NSArray* words = [NSArray arrayWithObjects:@"Apple", @"Apple", @"Orange", @"Apple", @"Orange", @"Pear", nil];
[words enumerateObjectsUsingBlock:^(NSString* str, NSUInteger idx, BOOL *stop) {
    for (int i = idx + 1; i < words.count; i++) {
        if ([str isEqualToString:[words objectAtIndex:i]]) {
            [duplicates addObject:str];
            break;
        }
    }
}];
NSLog(@"Dups: %@", [duplicates allObjects]); // Prints "Apple" and "Orange"

与 NSArray 不同,使用 NSSet 可确保不会多次添加字符串。显然,可以进行一些优化,但这应该是一个很好的起点。

【讨论】:

  • 我试过这个方法,但我得到一个编译器警告:“不兼容的块指针类型正在初始化'void (^)(struct NSString *, NSUInteger, BOOL *)', 预期的'void (^)( struct objc_object *, NSUInteger, BOOL *)'" 我想我应该写 "return str;"某处,但我不确定在哪里......
  • 啊,不,这不是问题所在。我正在使用比您更新的编译器版本,这允许我更改该内联块的参数类型。您需要将 ...UsingBlock:^(NSString* str... 更改为 ...UsingBlock:^(id str...
  • 啊,我试过 id,但我忘了删除 *.感谢您提醒我,它运行良好!
【解决方案3】:

我假设您想计算数组中单词的出现次数并输出计数超过 1 的单词。一个基本而详细的方法是:

// Make an array of words - some duplicates
NSArray *wordList = [[NSArray alloc] initWithObjects:
                    @"Apple", @"Banana", @"Pencil",
                    @"Steve Jobs", @"Kandahar",
                    @"Apple", @"Banana", @"Apple",
                    @"Pear", @"Pear", nil];

// Make an mutable dictionary - the key will be a word from the list
// and the value will be a number representing the number of times the
// word appears in the original array. It starts off empty.
NSMutableDictionary *wordCount = [[NSMutableDictionary alloc] init];

// In turn, take each word in the word list...
for (NSString *s in wordList) {

    int count = 1;

    // If the word is already in the dictionary
    if([wordCount objectForKey:s]) {

        // Increse the count by one
        count = [[wordCount objectForKey:s] intValue] + 1;

    }

    // Save the word count in the dictionary
    [wordCount setObject:[NSNumber numberWithInt:count] forKey:s];
}

// For each word...
for (NSString *s in [wordCount keysOfEntriesPassingTest:
                     ^(id key, id obj, BOOL *stop) {
                         if ([obj intValue] > 1) return YES; else return NO;
                     }]) {

    // print the word and the final count
    NSLog(@"%2d %@", [[wordCount objectForKey:s] intValue], s);

}

输出将是:

3 Apple
2 Pear
2 Banana

【讨论】:

  • 哇,好先进,谢谢!但是我只需要知道哪个单词有重复项。但你的对其他用途很有用。
  • 好的,我更改了答案以反映您的原始问题。它现在只输出计数大于 1 的单词。
猜你喜欢
  • 1970-01-01
  • 2011-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-14
  • 2019-11-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多