1

I am trying to find the number of times each character in a string is used. for example, in the string "wow" I would like to count the number of times the character "w" is used and the number of times the character "o" is used. I would then like to add these characters to an NSMutableArray. Is there a programmatic way to count the number of times all specific characters are used? To get the number of occurrences of ALL characters in an NSString? Or would I have to go through the process of counting the occurrences of each individual character separately?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Paolo
  • 11
  • 2
  • 1
    See http://stackoverflow.com/questions/15254031/is-there-a-simple-way-to-split-a-nsstring-into-an-array-of-characters for a way to process each character. But instead of using an array, use a counted set. – rmaddy May 15 '14 at 03:32

3 Answers3

3

See iOS - Most efficient way to find word occurrence count in a string

NSString     *string     = @"wow";
    NSCountedSet *countedSet = [NSCountedSet new];

    [string enumerateSubstringsInRange:NSMakeRange(0, [string length])
                               options:NSStringEnumerationByComposedCharacterSequences | NSStringEnumerationLocalized
                            usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop){

                                // This block is called once for each word in the string.
                                [countedSet addObject:substring];

                                // If you want to ignore case, so that "this" and "This"
                                // are counted the same, use this line instead to convert
                                // each word to lowercase first:
                                // [countedSet addObject:[substring lowercaseString]];
                            }];

    NSLog(@"%@", countedSet);
    NSLog(@"%@", [countedSet allObjects]);
    NSLog(@"%d", [countedSet countForObject:@"w"]);
Community
  • 1
  • 1
HMHero
  • 2,333
  • 19
  • 11
0

The exact answer depends on some questions -

  • Do you only want to count the characters a-z or do you want punctuation as well?
  • Do you need to count unicode characters or just 8 bit characters?
  • Is case important ie. is A different to a?

Assuming you only want to count 8 bit, a-z independent of case, you could use something like -

- (NSArray *)countCharactersInString:(NSString *)inputString
{
    NSMutableArray *result=[[NSMutableArray alloc]initWithCapacity:26];
    for (int i=0;i<26;i++) {
        [result addObject:[NSNumber numberWithInt:0]];
    }

    for (int i=0;i<[inputString length];i++)
    {
        unichar c=[inputString characterAtIndex:i];
        c=tolower(c);
        if (isalpha(c))
        {
            int index=c-'a';
            NSNumber *count=[result objectAtIndex:index];
            [result setObject:[NSNumber numberWithInt:[count intValue]+1]  atIndexedSubscript:index];
        }
    }

    return (result);
}

An alternative approach is to use an NSCountedSet - it handles all characterspunctuation etc, but will be 'sparse' - there is no entry for a character that is not present in the string. Also, the implementation below is case sensitive - W is different to w.

- (NSCountedSet *)countCharactersInString:(NSString *)inputString
{
  NSCountedSet *result=[[NSCountedSet alloc]init];
  for (int i=0;i<[inputString length];i++)
  {
    NSString *c=[inputString substringWithRange:NSMakeRange(i,1)];
    [result addObject:c];
  }
  return result;
}
Paulw11
  • 108,386
  • 14
  • 159
  • 186
  • 1
    The 2nd solution fails for any Unicode character with a value of `\U10000` or greater and with composed characters. – rmaddy May 15 '14 at 04:02
0
NSString *str = @"Program to Find the Frequency of Characters in a String";

NSMutableDictionary *frequencies = [[NSMutableDictionary alloc]initWithCapacity:52];

initWithCapacity:52 - capacity can be more depends on character set (for now : a-z, A-Z)

for (short i=0; i< [str length]; i++){
    short index = [str characterAtIndex:i];

    NSString *key   = [NSString stringWithFormat:@"%d",index];
    NSNumber *value = @1;

    short frequencyCount=0;
    if ([frequencies count] > 0 && [frequencies valueForKey:key]){

        frequencyCount = [[frequencies valueForKey:key] shortValue];
        frequencyCount++;

        value = [NSNumber numberWithShort:frequencyCount];

        [frequencies setValue:value forKey:key];
    }
    else{
       [frequencies setValue:value forKey:key];
    }
}

To display occurrence of each character in string

[frequencies enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
    NSString *ky = (NSString*)key;
    NSNumber *value = (NSNumber*)obj;

    NSLog(@"%c\t%d", ([ky intValue]), [value shortValue]);
}];