【问题标题】:What is the most efficient way to count number of word in NSString without using regex?在不使用正则表达式的情况下计算 NSString 中单词数的最有效方法是什么?
【发布时间】:2010-10-20 06:19:47
【问题描述】:

我对 Objective C 有点陌生,想知道是否有更好的方法来计算字符串中的单词。

即:

NSString *str = @"this is a string";

// return should be 4 words ..

我现在的方法是将字符串分解为一个单词空格('')字符数组并计算数组。

任何建议将不胜感激!谢谢!! :)

编辑: 对于那些来这里寻找答案的人;我发现了一个类似的帖子,回复很好。

How to count words within a text string?

【问题讨论】:

标签: ios objective-c cocoa nsstring


【解决方案1】:

有两种方法不涉及收集单词数组,并且应该比仅仅打破空格更聪明:

我会使用其中之一,即使我确实想收集或以其他方式使用这些词。

【讨论】:

  • 谢谢彼得!我不知道有一个 CFStringTokenizer 并且很高兴知道。我不想使用 NSRegularExpression 的原因是因为 IOS 4 唯一的限制。
  • 这个答案是最好的。查看 WWDC 2012 Session 215:Douglas Davidson 的文本和语言分析。一些示例代码:__block int wordCount =0; NSRange range = {0,self.text.length }; [self.text enumerateSubstringsInRange:range options:NSStringEnumerationByWords usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) { wordCount++; }];
【解决方案2】:

除非您打算每秒执行数百次,否则我会选择可读的解决方案,类似于以下伪代码:

def count (str):
    lastchar = " "
    count = 0
    for char as every character in string:
        if char is not whitespace and lastchar is whitespace:
            count = count + 1
        lastchar = char
    return count

创建一个完整的其他字符串数组只是为了计算它们并丢弃它们似乎有点浪费。

如果由于某种原因成为问题,您可以将函数体替换为更快的版本。但是,请确保它首先是一个问题。对已经足够快的代码进行优化是浪费精力。

【讨论】:

  • 感谢详细回复!我想我会抓住 char 指针并计算字符数。
  • 这不仅易于理解,而且可能比使用 RE 或通用扫描仪更有效。唯一棘手的部分是定义“空白”并提出一个好的算法来检查它,如果你想要一个通用的解决方案(而不是只检查空白)。”
【解决方案3】:

您确定那部分代码存在瓶颈吗?如果不是(这很可能),那么在空间上分割对我来说似乎完全可以接受。您可以创建一个 C 字符串并计算空格,但很多时候这种“优化”版本实际上比原始版本慢。也就是说,假设您当前的代码如下所示:

NSUInteger wordCount = [[someString componentsSeparatedByString:@" "] count];

这并不完全正确(请参阅@"___",其中下划线是空格),但也许您真的使用了正则表达式并在\s+ 上拆分?

【讨论】:

    【解决方案4】:

    在这种情况下,我会像这样使用 NSScanner:

    NSString *str = @"this is a string";
    NSScanner *scanner = [NSScanner scannerWithString:str];
    NSCharacterSet *whiteSpace = [NSCharacterSet whitespaceAndNewlineCharacterSet];
    NSCharacterSet *nonWhitespace = [whiteSpace invertedSet];
    int wordcount = 0;
    
    while(![scanner isAtEnd])
    {
        [scanner scanUpToCharactersFromSet:nonWhitespace intoString:nil];
        [scanner scanUpToCharactersFromSet:whitespace intoString:nil];
        wordcount++;
    }
    

    这只会创建两个额外的对象,不管字符串有多长。

    【讨论】:

    • 谢谢!一个问题,我希望这对你来说听起来并不愚蠢。 int wordcount -0 中的 -0 有什么作用?
    • 我认为应该是int wordcount = 0;。我会修复它,如果我错了,NSResponder 可以改回来。
    • 嗯...在我发布这个之前我以为我已经修正了那个错字。哎呀。
    • 这将无法正确处理@" "@" hello "
    • 这个解决方案比这个慢:stackoverflow.com/a/6171439/1033581
    【解决方案5】:

    用于将字符串存储到数组中

    NSArray *yourArray = [str componentsSeparatedByString:@" "];
    

    更新:

    并计算你可以使用的单词数

    [yourArray count]
    

    【讨论】:

    • 提问者在问题中说这是他已经在做的事情。
    • 是的,我正在这样做,并发现创建一个数组只是为了计数和丢弃有点浪费。谢谢!
    • 不准确,因为它不能正确处理连续的空格。
    【解决方案6】:

    此代码将计算字符串中包含的由任意数量的 空格换行符 字符分隔的单词(即非空子字符串)的数量:

    NSUInteger wordCount = 0;
    
    for (NSString* word in [someString
        componentsSeparatedByCharactersInSet:
        [NSMutableCharacterSet characterSetWithCharactersInString:@" \n"]]) {
    
        if (![word  isEqual: @""]) {
            wordCount++;
        }
    
    }
    

    在不重复使用正则表达式的情况下,对 zoul 的回答略有改进。

    【讨论】:

      【解决方案7】:

      一个线性精确的解决方案:

      return [[self componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"length > 0"]].count;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-06-12
        • 2011-12-11
        • 1970-01-01
        • 1970-01-01
        • 2011-07-13
        • 2011-08-05
        • 1970-01-01
        • 2011-05-02
        相关资源
        最近更新 更多