2009-06-02 148 views
31

我有一個NSStringNSMutableString並希望得到特定字符的出現次數。NSString中字符出現的次數

我需要爲相當多的字符做這個 - 在這種情況下大寫英文字符 - 所以它會很好,它是快速的。

回答

1

我可能會使用

NSString rangeOfCharacterFromSet:

rangeOfCharacterFromSet:options:range::

,其中集合是您要搜索的字符。它返回與第一個字符匹配的位置。保持數組或字典並增加字符數,然後重複。

+0

如果我理解正確的文檔,這將給予任何的設置字符的範圍。但我需要*每個*字符的數量。 – Elliot 2009-06-02 06:57:24

+1

我的想法是保留char - > count對的字典,然後獲取給定索引處的字符並將其計入字典中......或者您可以遍歷字符串並檢查每個字符是否在您的集合中,如果它然後增加它的數量 – stefanB 2009-06-02 07:28:55

7

當你在一個NSString尋找的東西,嘗試使用NSScanner第一。

NSString *yourString = @"ABCCDEDRFFED"; // For example 
NSScanner *scanner = [NSScanner scannerWithString:yourString]; 

NSCharacterSet *charactersToCount = @"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]; 
+0

我還沒有能夠得到這個工作。我正在計算空格的數量。 – lawrence 2009-12-24 20:15:51

+3

@lawrence默認情況下,NSScanner會忽略空格和空格。 – borrrden 2012-12-14 02:33:21

1

掃描儀的例子在iPhone上崩潰。我發現這個解決方案:

NSString *yourString = @"ABCCDEDRFFED"; // For example 
NSScanner *mainScanner = [NSScanner scannerWithString:yourString]; 
NSString *temp; 
NSInteger numberOfChar=0; 
while(![mainScanner isAtEnd]) 
{ 
    [mainScanner scanUpToString:@"C" intoString:&temp]; 
    numberOfChar++; 
    [mainScanner scanString:@"C" intoString:nil]; 
} 

它爲我工作,沒有崩潰。希望它可以幫助!

2

您的解決方案並沒有爲我工作,我在循環遞增numberOfChar添加的條件只有mainScanner已經達到字符串的結尾:

NSString *yourString = @"ABCCDEDRFFED"; // For example 
NSScanner *mainScanner = [NSScanner scannerWithString:yourString]; 
NSString *temp; 
NSInteger numberOfChar=0; 
while(![mainScanner isAtEnd]) 
{ 
    [mainScanner scanUpToString:@"C" intoString:&temp]; 
    if(![mainScanner isAtEnd]) { 
     numberOfChar++; 
     [mainScanner scanString:@"C" intoString:nil]; 
    } 
} 

注意,這是一個快速解決,我不沒有時間做一個優雅的解決方案...

96

你可以在一行中做到這一點。例如,該計算空格數量:

NSUInteger numberOfOccurrences = [[yourString componentsSeparatedByString:@" "] count] - 1; 
22

嘗試在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 

這一個比componentsSeparatedByString:方法快5倍左右。

5

如今浮現在我的腦海裏的東西一樣,第一件事:NSCountedSet

NSString *string [email protected]"AAATTC"; 

NSMutableArray *array = [@[] mutableCopy]; 

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

日誌:

C: 1 
G: 0 
A: 3 
T: 2 
0

這是一個斯威夫特3個版本,NSRange,範圍,字符串和NSString!享受:)

/// All ranges using NSString and NSRange 
/// Is usually used together with NSAttributedString 

extension NSString { 
    public func ranges(of searchString: String, options: CompareOptions = .literal, searchRange: NSRange? = nil) -> [NSRange] { 
     let searchRange = searchRange ?? NSRange(location: 0, length: self.length) 
     let subRange = range(of: searchString, options: options, range: searchRange) 
     if subRange.location != NSNotFound { 

      let nextRangeStart = subRange.location + subRange.length 
      let nextRange = NSRange(location: nextRangeStart, length: searchRange.location + searchRange.length - nextRangeStart) 
      return [subRange] + ranges(of: searchString, options: options, searchRange: nextRange) 
     } else { 
      return [] 
     } 
    } 
} 

/// All ranges using String and Range<Index> 
/// Is usually used together with NSAttributedString 

extension String { 
    public func ranges(of searchString: String, options: CompareOptions = [], searchRange: Range<Index>? = nil) -> [Range<Index>] { 
     if let range = range(of: searchString, options: options, range: searchRange, locale: nil) { 

      let nextRange = range.upperBound..<(searchRange?.upperBound ?? endIndex) 
      return [range] + ranges(of: searchString, searchRange: nextRange) 
     } else { 
      return [] 
     } 
    } 
} 
相關問題