2009-06-02 18 views
31

में एक कैरेक्टर के घटनाओं की संख्या मेरे पास NSString या NSMutableString है और आप किसी विशेष वर्ण की घटनाओं की संख्या प्राप्त करना चाहते हैं।एनएसएसटींग

मुझे कुछ मामलों के लिए ऐसा करने की ज़रूरत है - इस मामले में अपरकेस अंग्रेजी वर्ण - तो यह जल्दी होने के लिए अच्छा होगा।

उत्तर

1

मैं शायद का प्रयोग करेंगे

NSString rangeOfCharacterFromSet:

या

rangeOfCharacterFromSet:options:range::

जहां सेट वर्ण आप खोज रहे हैं का सेट है। यह सेट से मेल खाने वाले पहले अक्षर के स्थान के साथ आता है। सरणी या शब्दकोश रखें और चरित्र के लिए गिनती बढ़ाएं, फिर दोहराएं।

+0

यदि मैं दस्तावेज़ीकरण को सही ढंग से समझ रहा हूं, तो यह सेट में किसी भी वर्ण की सीमा प्रदान करेगा। लेकिन मुझे * प्रत्येक * चरित्र की गिनती की आवश्यकता है। – Elliot

+1

मेरा विचार char -> गिनती जोड़े का शब्दकोश रखना है और उसके बाद दिए गए इंडेक्स पर चार प्राप्त करें और शब्दकोश में इसकी गिनती बढ़ाएं ... या आप स्ट्रिंग पर फिर से सक्रिय हो सकते हैं और जांच सकते हैं कि प्रत्येक अक्षर आपके सेट में है या नहीं, अगर यह इसके बाद यह बढ़ता है – stefanB

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

+3

@lawrence डिफ़ॉल्ट रूप से, एनएसएससीनर द्वारा रिक्त स्थान और सफेद स्थान को अनदेखा किया जाता है। – borrrden

+3

आप 'setCharactersToBeSkipped को कॉल कर सकते हैं: (NSCharacterSet *) skipSet'' nil' के साथ 'skipSet' के रूप में - और 'NSScanner' किसी भी वर्ण को नहीं छोड़ेगा। –

1

स्कैनर के साथ उदाहरण आईफोन पर क्रैश हो रहा था। मुझे यह समाधान मिला:

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; 
+5

हालांकि एक अस्थायी सरणी बनाता है .. गति के लिए, [जैक का जवाब] (http://stackoverflow.com/a/15947190/482601) को प्राथमिकता दी जानी चाहिए। – fabian789

+1

क्या यह 'yourString' की शुरुआत और अंत में एक स्थान की गणना करता है? –

+0

गति अंतर केवल तभी मायने रखता है यदि आप इसे हजारों बार कर रहे हैं। –

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 

यह एक लगभग 5 बार componentsSeparatedByString: दृष्टिकोण की तुलना में तेजी है उदाहरण के लिए, इस रिक्त स्थान की संख्या की गणना।

+0

यह श्रेणी ठीक काम करती है, लेकिन मेरे पास एक सवाल है: क्या आप यूनीचर (CFString.h से) और unichar (NSString से) दोनों का उपयोग कर सकते हैं? – Bjinse

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, रेंज, स्ट्रिंग के लिए है और एनएसएसटींग! आनंद लें :)

/// 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 [] 
     } 
    } 
}