检查字符串是否包含数字

时间:2013-08-14 10:20:35

标签: ios objective-c

我想检查NSString是否包含每个数字(0-9)超过5次。我不需要知道哪个数字或多少次,我只是想让它返回TRUE或False,以确定字符串中是否包含任何数字超过5次。我希望它尽可能高效。

我已经考虑过了一些想法,其中很长的路要走的是将所有10位数字(再次为0-9)放在一个数组中,然后遍历每个数字,将它与字符串进行比较。如果字符串中有超过5个匹配项,请放置一个将返回true的标志。

有人能告诉我是否有“更好”或更有效的方法解决这个问题?

谢谢!

4 个答案:

答案 0 :(得分:3)

这可能不是“最好”的做事方式,但这对我来说是最有趣的方式,它使用基金会使用字符集,计数集和基于块的字符串枚举。

// Your string
NSString *myString = @"he11o 12345 th1s 55 1s 5 very fun 55 1ndeed.";

// A set of all numeric characters
NSCharacterSet *numbers = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
NSUInteger digitThreshold = 5;

// An emtpy counted set
NSCountedSet *numberOccurances = [NSCountedSet new];

// Loop over all the substrings as composed characters
// this will not have the same issues with e.g. Chinese characters as
// using a C string would. (Available since iOS 4)
[myString enumerateSubstringsInRange:NSMakeRange(0, myString.length)
                             options:NSStringEnumerationByComposedCharacterSequences
                          usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
                              // Check if substring is part of numeric set of characters
                              if ([substring rangeOfCharacterFromSet:numbers].location != NSNotFound) {
                                  [numberOccurances addObject:substring];
                                  // Check if that number has occurred more than 5 times
                                  if ([numberOccurances countForObject:substring] > digitThreshold) {
                                      *stop = YES;
                                      // Do something here based on that fact
                                      NSLog(@"%@ occured more than %d times", substring, digitThreshold);
                                  }
                              }
                          }];

如果你不让它停止,那么它将继续计算该字符串中所有数字的出现次数。

如果您记录计数的集合看起来像这样(方括号内的数字是计数):

<NSCountedSet: 0xa18d830> (3 [1], 1 [6], 4 [1], 2 [1], 5 [6])

答案 1 :(得分:2)

此代码尝试尽可能高效。

BOOL checkDigits(NSString *string)
{
    // get the raw UTF-16 code fragments, hopefully without a copy
    const UniChar *characters = CFStringGetCharactersPtr((__bridge CFStringRef)string);
    NSData *characterData = nil;
    if (characters == NULL) {
        characterData = [string dataUsingEncoding:NSUTF16StringEncoding];
        characters = [characterData bytes];
    }

    // initialize 10 individual counters for digits
    int digitCount[10] = {};
    NSUInteger length = [string length];

    // loop over the characters once
    for (NSUInteger i = 0; i != length; ++i) {
        UniChar c = characters[i];

        // UTF-16 encodes ASCII digits as their values
        if (c >= '0' && c <= '9') {
            int idx = c - '0';
            if (digitCount[idx] == 4)
                return YES;
            digitCount[idx] += 1;
        }
    }

    // keep the NSData object alive until here
    [characterData self];

    return NO;
}

答案 2 :(得分:0)

使用以下代码检查字符串是否包含0-9:

NSUInteger count = 0, length = [yourString length];
    NSRange range = NSMakeRange(0, length); 
    while(range.location != NSNotFound)
   {
     range = [yourString rangeOfString: @"hello" options:0 range:range];
     if(range.location != NSNotFound)
     {
        range = NSMakeRange(range.location + range.length, length - (range.location + range.length));
       count++; 
    }
  }

答案 3 :(得分:-1)

NSString *materialnumber =[[self.documentItemsArray objectAtIndex:indexPath.row] getMATERIAL_NO];
            NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES '[0-9*]+'"];
            if ([predicate evaluateWithObject:materialnumber])
            {
                materialnumber = [NSString stringWithFormat:@"%d",[materialnumber intValue]];
            }