我想检查一个 NSString 是否包含每个可能的数字(0-9)超过 5 次。我不需要知道哪个数字或多少次,我只是希望它返回 TRUE 或 False,以确定字符串中是否包含任何数字超过 5 次。我希望它尽可能高效。
我已经给它一些想法,并且要解决它的漫长方法是将所有 10 个数字(同样是 0-9)放在一个数组中,然后循环遍历每个数字,将其与字符串进行比较。如果字符串中有超过 5 个匹配项,则放置一个返回 true 的标志。
谁能告诉我是否有解决这个问题的“更好”或更有效的方法?
谢谢!
我想检查一个 NSString 是否包含每个可能的数字(0-9)超过 5 次。我不需要知道哪个数字或多少次,我只是希望它返回 TRUE 或 False,以确定字符串中是否包含任何数字超过 5 次。我希望它尽可能高效。
我已经给它一些想法,并且要解决它的漫长方法是将所有 10 个数字(同样是 0-9)放在一个数组中,然后循环遍历每个数字,将其与字符串进行比较。如果字符串中有超过 5 个匹配项,则放置一个返回 true 的标志。
谁能告诉我是否有解决这个问题的“更好”或更有效的方法?
谢谢!
这可能不是“最好”的做事方式,但它对我来说是最有趣的方式,它很好地利用了 Foundation 使用字符集、计数集和基于块的字符串枚举。
// 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])
此代码尝试尽可能提高性能。
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;
}
使用以下代码检查字符串是否包含 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++;
}
}
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]];
}