Ell*_*iot 36 string cocoa cocoa-touch character nsstring
我有一个NSString
或者NSMutableString
想要获得特定角色的出现次数.
我需要为很多字符做这个 - 在这种情况下是大写的英文字符 - 所以它很快就会很好.
gba*_*aor 100
您可以在一行中执行此操作.例如,这会计算空格数:
NSUInteger numberOfOccurrences = [[yourString componentsSeparatedByString:@" "] count] - 1;
Run Code Online (Sandbox Code Playgroud)
Jac*_*que 25
在NSString上尝试此类别:
@implementation NSString (OccurrenceCount)
- (NSUInteger)occurrenceCountOfCharacter:(UniChar)character
{
CFStringRef selfAsCFStr = (__bridge CFStringRef)self;
CFStringInlineBuffer inlineBuffer;
CFIndex length = CFStringGetLength(selfAsCFStr);
CFStringInitInlineBuffer(selfAsCFStr, &inlineBuffer, CFRangeMake(0, length));
NSUInteger counter = 0;
for (CFIndex i = 0; i < length; i++) {
UniChar c = CFStringGetCharacterFromInlineBuffer(&inlineBuffer, i);
if (c == character) counter += 1;
}
return counter;
}
@end
Run Code Online (Sandbox Code Playgroud)
这个componentsSeparatedByString:
方法比方法快约5倍.
Cyn*_*ing 16
replaceOccurrencesOfString:withString:options:range:
将返回a中替换的字符数NSMutableString
.
[string replaceOccurrencesOfString:@"A"
withString:@"B"
options:NSLiteralSearch
range:NSMakeRange(0, [receiver length])];
Run Code Online (Sandbox Code Playgroud)
无论何时在寻找a中的东西NSString
,请先尝试使用NSScanner
.
NSString *yourString = @"ABCCDEDRFFED"; // For example
NSScanner *scanner = [NSScanner scannerWithString:yourString];
NSCharacterSet *charactersToCount = [NSCharacterSet characterSetWithCharactersInString:@"C"]; // For example
NSString *charactersFromString;
if (!([scanner scanCharactersFromSet:charactersToCount
intoString:&charactersFromString])) {
// No characters found
NSLog(@"No characters found");
}
// should return 2 for this
NSInteger characterCount = [charactersFromString length];
Run Code Online (Sandbox Code Playgroud)
现在,我想到的第一件事就是:NSCountedSet
NSString *string = @"AAATTC";
NSMutableArray *array = [NSMutableArray array];
[string enumerateSubstringsInRange:NSMakeRange(0, [string length]) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
[array addObject:substring];
}] ;
NSCountedSet * set = [[NSCountedSet alloc] initWithArray:array];
for (NSString *nucleobase in @[@"C", @"G", @"A", @"T"]){
NSUInteger count = [set countForObject:nucleobase];
NSLog(@"%@: %lu", nucleobase, (unsigned long)count);
}
Run Code Online (Sandbox Code Playgroud)
日志:
C: 1
G: 0
A: 3
T: 2
Run Code Online (Sandbox Code Playgroud)
不同 Objective-C 解决方案的性能比较。
假设以下所有方法都是 NSString 扩展(内部@implementation NSString (CountOfOccurrences)
)。
作为示例,我使用了一个随机生成的长度为 100000000 的字符串,其中使用所有拉丁字符(CharacterSet(charactersIn: "\u{0020}"..."\u{036F}")
在 Swift 中)。要计算的字符是@"a"
。
在模拟器上的 Xcode 10.3 上以发布配置进行测试。
有两种方法来计算字符:使用NSLiteralSearch
或不使用。计数会不同,性能会受到根本性影响。为了获得最快的结果,我们将执行精确的逐个字符等效。以下四种解决方案给出了非常接近的性能结果。
使用replaceOccurrencesOfString:withString:options:range:
。这是所有场景中最快的解决方案:即使您替换NSLiteralSearch
为kNilOptions
,您仍然比 pierrot3887 扫描仪解决方案更快。
- (NSUInteger)countOccurrencesOfString:(NSString *)stringToFind
{
return [[NSMutableString stringWithString:self] replaceOccurrencesOfString:stringToFind
withString:stringToFind
options:NSLiteralSearch
range:NSMakeRange(0, self.length)];
}
Run Code Online (Sandbox Code Playgroud)
使用stringByReplacingOccurrencesOfString:withString:options:range:
。
- (NSUInteger)countOccurrencesOfString:(NSString *)stringToFind
{
NSString *strippedString = [self stringByReplacingOccurrencesOfString:stringToFind
withString:@""
options:NSLiteralSearch
range:NSMakeRange(0, self.length)];
return (self.length - strippedString.length) / stringToFind.length;
}
Run Code Online (Sandbox Code Playgroud)
使用CFStringGetCharacterFromInlineBuffer
。请参阅/sf/answers/1116303331/。
使用rangeOfString:options:range:
。
- (NSUInteger)countOccurrencesOfString:(NSString *)stringToFind
{
//assert(stringToFind.length);
NSUInteger count = 0;
NSRange searchRange = NSMakeRange(0, self.length);
NSRange foundRange;
while ((void)(foundRange = [self rangeOfString:stringToFind options:NSLiteralSearch range:searchRange]), foundRange.length) {
count += 1;
NSUInteger loc = NSMaxRange(foundRange);
searchRange = NSMakeRange(loc, self.length - loc);
}
return count;
}
Run Code Online (Sandbox Code Playgroud)
以下解决方案不使用NSLiteralSearch
也不执行精确的逐字符等效。前两个可能比快速解决方案慢 10 倍,最后一个可能慢 100 倍。
使用scanUpToString:intoString:
。遗憾的是,它NSScanner
没有提供精确的逐个字符等效的选项。
- (NSUInteger)countOccurrencesOfString:(NSString *)stringToFind
{
NSScanner *scanner = [NSScanner scannerWithString:self];
scanner.charactersToBeSkipped = nil;
scanner.caseSensitive = YES;
NSUInteger numberOfOccurrences = 0;
while (!scanner.isAtEnd) {
[scanner scanUpToString:stringToFind intoString:nil];
if (!scanner.isAtEnd) {
numberOfOccurrences++;
[scanner scanString:stringToFind intoString:nil];
}
}
return numberOfOccurrences;
}
Run Code Online (Sandbox Code Playgroud)
使用componentsSeparatedByString:
。关于单行可行的论点,请注意,上面给出的最快解决方案也是单行。
- (NSUInteger)countOccurrencesOfString:(NSString *)stringToFind
{
return [self componentsSeparatedByString:stringToFind].count - 1;
}
Run Code Online (Sandbox Code Playgroud)
使用enumerateSubstringsInRange:options:usingBlock:
。
- (NSUInteger)countOccurrencesOfCharacter:(NSString *)characterToFind
{
__block NSUInteger counter = 0;
[self enumerateSubstringsInRange:NSMakeRange(0, self.length) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
if ([characterToFind isEqualToString:substring]) counter += 1;
}];
return counter;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
34306 次 |
最近记录: |