Как я могу получить количество раз NSString (например, @"cake"
) появляется в большем NSString (например, @"Cheesecake, apple cake, and cherry pie"
)?
Я должен сделать это на большом количестве строк, таким образом независимо от того, что метод, который я использую, должен был бы быть относительно быстрым.
Спасибо!
Ruby автоматически обрабатывает необработанные аргументы как имена файлов, затем открывает и считывает файлы, делая входные данные доступными для ARGF
( $ <
). По умолчанию получает
чтения из ARGF. Чтобы обойти это:
$stdin.gets
Было предложено использовать STDIN
вместо $ stdin
, но обычно лучше использовать $ stdin
.
Кроме того, после получения входных данных из ARGV
, вы можете использовать:
ARGV.clear
Тогда вы будете свободны, чтобы получает
без чтения из файлов, которые вы, возможно, не хотели читать.
Целая точка Kernel # gets
- это обработка аргументов, переданных программе, как имен файлов и чтение этих файлов. Первое предложение в документации гласит:
Возвращает (и присваивает $ _) следующую строку из списка файлов в ARGV (или $ *)
Именно так получает
. Если требуется выполнить чтение из определенного объекта ввода-вывода
(например, $ stdin
), просто вызовите получает
для этого объекта.
Это не протестировано, но должно быть хорошим началом.
NSUInteger count = 0, length = [str length];
NSRange range = NSMakeRange(0, length);
while(range.location != NSNotFound)
{
range = [str rangeOfString: @"cake" options:0 range:range];
if(range.location != NSNotFound)
{
range = NSMakeRange(range.location + range.length, length - (range.location + range.length));
count++;
}
}
Есть пара параметров, которыми вы могли бы сделать это. Вы могли бы позвать RansefString
RangeOfString: Варианты: Диапазон:
, или вы могли бы сделать что-то вроде:
NSArray * portions = [aString componentsSeparatedByString:@"cake"];
NSUInteger cakeCount = [portions count] - 1;
Редактировать Я снова думал об этом вопросе, и я написал алгоритм линейного времени, чтобы сделать поиск (Линейный до длины строки стога HayStack):
+ (NSUInteger) numberOfOccurrencesOfString:(NSString *)needle inString:(NSString *)haystack {
const char * rawNeedle = [needle UTF8String];
NSUInteger needleLength = strlen(rawNeedle);
const char * rawHaystack = [haystack UTF8String];
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;
}
Если семантика удаления на ссылке объекта будет делать все остальные ссылки, ссылающиеся на то, что объект будет нулевым, то вы могли бы сделать это с 2 уровнями косвения (1 больше, чем вы подсказки). Хотя обратите внимание, что, в то время как базовый объект будет уничтожен, должен быть сохранен фиксированный объем информации (достаточно для хранения ссылки), должен храниться на куче.
Все ссылки У пользователя использует, будет ссылаться на скрытую ссылку (предположительно живущий в куче) к реальному объекту. При выполнении некоторой операции на объекте (например, вызов метода или полагаться на его идентичность, Wuch, используя оператор ==), эталонная система программиста использует, будет разыменовать скрытую ссылку. При удалении объекта фактический объект будет удален из кучи, а скрытая ссылка будет установлена на NULL. Таким образом, программисты ссылок увидят оценку в NULL.
Было бы задание GC, чтобы очистить эти скрытые ссылки.
-121--3714106-Нет встроенного метода. Я бы предложил вернуть C-String и используя общий алгоритм стиля C-String для подсчета подстроки ... Если вам действительно нужно это быть быстрым.
Если вы хотите остаться в объекте C, это может помочь ссылку . Он описывает основной поиск подстроки для NSString. Если вы работаете с диапазонами, отрегулируйте и подсчитаете, у вас будет «чистый» объективное решение C ... хотя и медленно.
Вот версия, выполняемая в качестве расширения NSString
(та же идея, как ответ Мэтью Фласчен):
@interface NSString (my_substr_search)
- (unsigned) countOccurencesOf: (NSString *)subString;
@end
@implementation NSString (my_substring_search)
- (unsigned) countOccurencesOf: (NSString *)subString {
unsigned count = 0;
unsigned myLength = [self length];
NSRange uncheckedRange = NSMakeRange(0, myLength);
for(;;) {
NSRange foundAtRange = [self rangeOfString:subString
options:0
range:uncheckedRange];
if (foundAtRange.location == NSNotFound) return count;
unsigned newLocation = NSMaxRange(foundAtRange);
uncheckedRange = NSMakeRange(newLocation, myLength-newLocation);
count++;
}
}
@end
<somewhere> {
NSString *haystack = @"Cheesecake, apple cake, and cherry pie";
NSString *needle = @"cake";
unsigned count = [haystack countOccurencesOf: needle];
NSLog(@"found %u time%@", count, count == 1 ? @"" : @"s");
}
Если вы хотите считать слова, а не только подстроки, то используйте CFStringTokenizer.
for(int i =0;i<htmlsource1.length-search.length;i++){
range = NSMakeRange(i,search.length);
checker = [htmlsource1 substringWithRange:range];
if ([search isEqualToString:checker]) {
count++;
}
}