Objective-C: How to find the most common string in

2020-04-11 18:42发布

问题:

I have an array of strings from an online database that I trying to determine the most commonly used word. The values inside the arrays will vary but I want to check the most common words of whatever collection or words I'm using. If theoretically I had an array of the following...

NSArray *stringArray = [NSArray arrayWithObjects:@"Duck", @"Duck", @"Duck", @"Duck", @"Goose"];

How do I iterate through this array to determine the most common string, which would obviously be "Duck"?

回答1:

Simplest way is probably NSCountedSet:

NSCountedSet* stringSet = [[NSCountedSet alloc] initWithArray:strings];
NSString* mostCommon = nil;
NSUInteger highestCount = 0;

for(NSString* string in stringSet) {
    NSUInteger count = [stringSet countForObject:string];
    if(count > highestCount) {
        highestCount = count;
        mostCommon = string;
    }
}


回答2:

You can use the word as a key into a dictionary.

NSMutableDictionary *words = [NSMutableDictionary dictionary];
for (NSString *word in stringArray) {
    if (!words[word]) {
        [words setValue:[NSDecimalNumber zero] forKey:word];
    }

    words[word] = [words[word] decimalNumberByAdding:[NSDecimalNumber one]];
}

Now iterate through words and find the key with the highest value.

NSString *mostCommon;
NSDecimalNumber *curMax = [NSDecimalNumber zero];
for (NSString *key in [words allKeys]) {
    if ([words[key] compare:curMax] == NSOrderedDescending) {
        mostCommon = key;
        curMax = word[key];
    }
}

NSLog(@"Most Common Word: %@", mostCommon);

EDIT: Rather than looping through the array once then looping separately through the sorted dictionary, I think we can do better and do it all in a single loop.

NSString *mostCommon;
NSDecimalNumber *curMax = [NSDecimalNumber zero];
NSMutableDictionary *words = [NSMutableDictionary dictionary];
for (NSString *word in stringArray) {
    if (!words[word]) {
        [words setValue:[NSDecimalNumber zero] forKey:word];
    }

    words[word] = [words[word] decimalNumberByAdding:[NSDecimalNumber one]];

    if ([words[word] compare:curMax] == NSOrderedDescending) {
        mostCommon = word;
        curMax = words[word];
    }
}

NSLog(@"Most Common Word: %@", mostCommon);

This should be significantly faster than my answer pre-edit, though I don't know how it compares to using the NSCountedSet answer.



回答3:

Try using NSPredicate.

NSUInteger count=0;
NSString *mostCommonStr;
for(NSString *strValue in stringArray) {
   NSUInteger countStr=[[stringArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self MATCHES[CD] %@, strValue]]count];
   if(countStr > count) {
       count=countStr;
       mostCommonStr=strValue;
   }
}
NSLog(@"The most commonstr is %@",mostCommonStr);