【问题标题】:How do I count the occurrences of ALL characters of a string?如何计算字符串中所有字符的出现次数?
【发布时间】:2014-07-03 08:06:38
【问题描述】:

我试图找出字符串中每个字符的使用次数。例如,在字符串“wow”中,我想计算使用字符“w”的次数和使用字符“o”的次数。然后我想将这些字符添加到 NSMutableArray。是否有一种编程方式来计算所有特定字符的使用次数?要获取 NSString 中所有字符的出现次数?还是我必须分别计算每个字符的出现次数?

【问题讨论】:

标签: ios objective-c string


【解决方案1】:

确切的答案取决于一些问题 -

  • 您只想计算字符 a-z 还是还要计算标点符号?
  • 您需要计算 unicode 字符还是仅计算 8 位字符?
  • 大小写是否重要,即。 A 和 a 有什么不同?

假设您只想计算 8 位,a-z 独立于大小写,您可以使用类似 -

- (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);
}

另一种方法是使用 NSCountedSet - 它处理所有字符标点符号等,但将是“稀疏”的 - 没有字符串中不存在的字符的条目。此外,下面的实现区分大小写 - W 与 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;
}

【讨论】:

  • 对于任何具有\U10000 或更大值且具有组合字符的Unicode 字符,第二个解决方案均失败。
【解决方案2】:

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"]);

【讨论】:

    【解决方案3】:
    NSString *str = @"Program to Find the Frequency of Characters in a String";
    
    NSMutableDictionary *frequencies = [[NSMutableDictionary alloc]initWithCapacity:52];
    

    initWithCapacity:52 - 容量可以更多地取决于字符集(现在: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];
        }
    }
    

    显示字符串中每个字符的出现

    [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]);
    }];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-03
      • 2010-09-21
      • 2015-12-01
      • 2014-04-24
      • 2011-12-16
      • 1970-01-01
      • 2020-02-21
      相关资源
      最近更新 更多