Nombre d’occurrences d’une sous-chaîne dans une NSSsortingng?

Comment puis-je obtenir le nombre de fois qu’un NSSsortingng (par exemple, @"cake" ) apparaît dans un NSSsortingng plus grand (par exemple, @"Cheesecake, apple cake, and cherry pie" )?

Je dois le faire sur beaucoup de chaînes, alors quelle que soit la méthode que j’utilise, elle doit être relativement rapide.

Merci!

Ce n’est pas testé, mais devrait être un bon début.

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

Une regex comme celle ci-dessous devrait faire le travail sans interaction en boucle …

Édité

 NSSsortingng *ssortingng = @"Lots of cakes, with a piece of cake."; NSError *error = NULL; NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"cake" options:NSRegularExpressionCaseInsensitive error:&error]; NSUInteger numberOfMatches = [regex numberOfMatchesInSsortingng:ssortingng options:0 range:NSMakeRange(0, [ssortingng length])]; NSLog(@"Found %i",numberOfMatches); 

Disponible uniquement sur iOS 4.x et supérieurs.

cherchait une meilleure méthode que la mienne mais voici un autre exemple:

 NSSsortingng *find = @"cake"; NSSsortingng *text = @"Cheesecake, apple cake, and cherry pie"; NSInteger strCount = [text length] - [[text ssortingngByReplacingOccurrencesOfSsortingng:find withSsortingng:@""] length]; strCount /= [find length]; 

J’aimerais savoir laquelle est la plus efficace.

Et j’ai créé une catégorie NSSsortingng pour un meilleur usage:

 // NSSsortingng+CountSsortingng.m @interface NSSsortingng (CountSsortingng) - (NSInteger)countOccurencesOfSsortingng:(NSSsortingng*)searchSsortingng; @end @implementation NSSsortingng (CountSsortingng) - (NSInteger)countOccurencesOfSsortingng:(NSSsortingng*)searchSsortingng { NSInteger strCount = [self length] - [[self ssortingngByReplacingOccurrencesOfSsortingng:searchSsortingng withSsortingng:@""] length]; return strCount / [searchSsortingng length]; } @end 

il suffit de l’appeler par:

 [text countOccurencesOfSsortingng:find]; 

Facultatif: vous pouvez le modifier pour effectuer une recherche insensible à la casse en définissant des options:

Il y a plusieurs façons de le faire. Vous pouvez appeler itérativement rangeOfSsortingng:options:range: ou vous pouvez faire quelque chose comme:

 NSArray * portions = [aSsortingng componentsSeparatedBySsortingng:@"cake"]; NSUInteger cakeCount = [portions count] - 1; 

EDIT Je pensais à cette question et j’ai écrit un algorithme linéaire pour effectuer la recherche (linéaire à la longueur de la chaîne de foin):

 + (NSUInteger) numberOfOccurrencesOfSsortingng:(NSSsortingng *)needle inSsortingng:(NSSsortingng *)haystack { const char * rawNeedle = [needle UTF8Ssortingng]; NSUInteger needleLength = strlen(rawNeedle); const char * rawHaystack = [haystack UTF8Ssortingng]; NSUInteger haystackLength = strlen(rawHaystack); NSUInteger needleCount = 0; NSUInteger needleIndex = 0; for (NSUInteger index = 0; index < haystackLength; ++index) { const char thisCharacter = rawHaystack[index]; if (thisCharacter != rawNeedle[needleIndex]) { needleIndex = 0; //they don't match; reset the needle index } //resetting the needle might be the beginning of another match if (thisCharacter == rawNeedle[needleIndex]) { needleIndex++; //char match if (needleIndex >= needleLength) { needleCount++; //we completed finding the needle needleIndex = 0; } } } return needleCount; } 

Une solution plus rapide, mais probablement moins efficace.

 - (int)numberOfOccurencesOfSubssortingng:(NSSsortingng *)subssortingng inSsortingng:(NSSsortingng*)ssortingng { NSArray *components = [ssortingng componentsSeparatedBySsortingng:subssortingng]; return components.count-1; // Two subssortingng will create 3 separated ssortingngs in the array. } 

Voici une version faite comme une extension de NSSsortingng (même idée que la réponse de Matthew Flaschen):

 @interface NSSsortingng (my_substr_search) - (unsigned) countOccurencesOf: (NSSsortingng *)subSsortingng; @end @implementation NSSsortingng (my_subssortingng_search) - (unsigned) countOccurencesOf: (NSSsortingng *)subSsortingng { unsigned count = 0; unsigned myLength = [self length]; NSRange uncheckedRange = NSMakeRange(0, myLength); for(;;) { NSRange foundAtRange = [self rangeOfSsortingng:subSsortingng options:0 range:uncheckedRange]; if (foundAtRange.location == NSNotFound) return count; unsigned newLocation = NSMaxRange(foundAtRange); uncheckedRange = NSMakeRange(newLocation, myLength-newLocation); count++; } } @end  { NSSsortingng *haystack = @"Cheesecake, apple cake, and cherry pie"; NSSsortingng *needle = @"cake"; unsigned count = [haystack countOccurencesOf: needle]; NSLog(@"found %u time%@", count, count == 1 ? @"" : @"s"); } 

Si vous voulez compter les mots , pas seulement les sous-chaînes, utilisez CFSsortingngTokenizer .

Voici une autre version en tant que catégorie sur NSSsortingng:

 -(NSUInteger) countOccurrencesOfSubssortingng:(NSSsortingng *) subssortingng { if ([self length] == 0 || [subssortingng length] == 0) return 0; NSInteger result = -1; NSRange range = NSMakeRange(0, 0); do { ++result; range = NSMakeRange(range.location + range.length, self.length - (range.location + range.length)); range = [self rangeOfSsortingng:subssortingng options:0 range:range]; } while (range.location != NSNotFound); return result; } 

Solution rapide serait:

 var numberOfSubssortingngAppearance = 0 let length = count(text) var range: Range? = Range(start: text.startIndex, end: advance(text.startIndex, length)) while range != nil { range = text.rangeOfSsortingng(subssortingng, options: NSSsortingngCompareOptions.allZeros, range: range, locale: nil) if let rangeUnwrapped = range { let remainingLength = length - distance(text.startIndex, rangeUnwrapped.endIndex) range = Range(start: rangeUnwrapped.endIndex, end: advance(rangeUnwrapped.endIndex, remainingLength)) numberOfSubssortingngAppearance++ } } 

La réponse de Matthew Flaschen a été un bon début pour moi. Voici ce que j’ai fini par utiliser sous la forme d’une méthode. J’ai adopté une approche légèrement différente de la boucle. Cela a été testé avec des chaînes vides passées à ssortingngToCount et text et avec la chaîne ssortingngToCount apparaissant comme le premier et / ou le dernier caractère du texte.

J’utilise cette méthode régulièrement pour compter les paragraphes du texte transmis (par exemple, ssortingngToCount = @ “\ r”).

J’espère que cela sera utile à quelqu’un.

  - (int)countSsortingng:(NSSsortingng *)ssortingngToCount inText:(NSSsortingng *)text{ int foundCount=0; NSRange range = NSMakeRange(0, text.length); range = [text rangeOfSsortingng:ssortingngToCount options:NSCaseInsensitiveSearch range:range locale:nil]; while (range.location != NSNotFound) { foundCount++; range = NSMakeRange(range.location+range.length, text.length-(range.location+range.length)); range = [text rangeOfSsortingng:ssortingngToCount options:NSCaseInsensitiveSearch range:range locale:nil]; } return foundCount; } 

Exemple d’appel supposant que la méthode est dans une classe nommée myHelperClass …

 int foundCount = [myHelperClass countSsortingng:@"n" inText:@"Now is the time for all good men to come to the aid of their country"]; 
 for(int i =0;i 

Pas de méthode intégrée. Je suggère de renvoyer une chaîne de caractères et d’utiliser un algorithme de style c-ssortingng commun pour le comptage des sous-chaînes … si vous avez vraiment besoin de cela rapidement.

Si vous souhaitez restr dans l’objective C, ce lien pourrait vous aider. Il décrit la recherche de base de sous-chaîne pour NSSsortingng. Si vous travaillez avec les gammes, ajustez et comptez, vous aurez alors une solution “pure” Objective C … bien que lente.

 -(IBAction)search:(id)sender{ int maincount = 0; for (int i=0; i<[self.txtfmainStr.text length]; i++) { char c =[self.substr.text characterAtIndex:0]; char cMain =[self.txtfmainStr.text characterAtIndex:i]; if (c == cMain) { int k=i; int count=0; for (int j = 0; j<[self.substr.text length]; j++) { if (k ==[self.txtfmainStr.text length]) { break; } if ([self.txtfmainStr.text characterAtIndex:k]==[self.substr.text characterAtIndex:j]) { count++; } if (count==[self.substr.text length]) { maincount++; } k++; } } NSLog(@"%d",maincount); } }