2013-08-14 4 views
1

Я хотел бы проверить, содержит ли NSString каждую цифру (0-9) более 5 раз. Мне не нужно знать, какую цифру или сколько раз, я просто хочу, чтобы она возвращала TRUE или False для того, содержит ли какая-либо из цифр более 5 раз в строке. Я бы хотел, чтобы он был максимально эффективным.Проверьте, содержит ли строка число цифр

Я подумал об этом, и долгий путь - разместить все 10 цифр (снова 0-9) в массиве и затем пропустить каждую цифру, сравнивая ее со строкой. Если в строке больше 5 совпадений, поместите флаг, который вернет true.

Может ли кто-нибудь сказать мне, есть ли «лучший» или более эффективный способ решения этой проблемы?

Спасибо!

+0

Вы разрешили иметь, например, 4444123 (более 5 цифр, но ни одна цифра не появится более чем в 5 раз) или это просто не более 5 цифр в строке? –

+0

@ DavidRönnqvist Извините, что не уточнил Дэвида. Строка может быть неограниченной длины, но никакая цифра не должна отображаться более 5 раз. Благодаря! – Teddy13

+0

Пожалуйста, frefer http://stackoverflow.com/questions/4663438/objective-c-find-numbers-in-string –

ответ

2

Этот код пытается быть производительным, насколько это возможно.

BOOL checkDigits(NSString *string) 
{ 
    // get the raw UTF-16 code fragments, hopefully without a copy 
    const UniChar *characters = CFStringGetCharactersPtr((__bridge CFStringRef)string); 
    NSData *characterData = nil; 
    if (characters == NULL) { 
     characterData = [string dataUsingEncoding:NSUTF16StringEncoding]; 
     characters = [characterData bytes]; 
    } 

    // initialize 10 individual counters for digits 
    int digitCount[10] = {}; 
    NSUInteger length = [string length]; 

    // loop over the characters once 
    for (NSUInteger i = 0; i != length; ++i) { 
     UniChar c = characters[i]; 

     // UTF-16 encodes ASCII digits as their values 
     if (c >= '0' && c <= '9') { 
      int idx = c - '0'; 
      if (digitCount[idx] == 4) 
       return YES; 
      digitCount[idx] += 1; 
     } 
    } 

    // keep the NSData object alive until here 
    [characterData self]; 

    return NO; 
} 
+1

ОП спросил, есть ли лучший алгоритм, чем это. –

+1

@RobvanderVeer Я понимаю его алгоритм по-разному: он выполняет итерацию по строке для каждой возможной цифры, в то время как это предложение имеет десять счетчиков для каждой цифры и пересекает строку только один раз. –

+0

@ RobvanderVeer Вы правы, я имел в виду нечто подобное, но код работает очень хорошо, и я думаю, вы не ошибетесь, вернувшись к основам. Также, исходя из других ответов, кажется, что это так же эффективно, как и получается :). Спасибо, Николай! – Teddy13

-1
NSString *materialnumber =[[self.documentItemsArray objectAtIndex:indexPath.row] getMATERIAL_NO]; 
      NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES '[0-9*]+'"]; 
      if ([predicate evaluateWithObject:materialnumber]) 
      { 
       materialnumber = [NSString stringWithFormat:@"%d",[materialnumber intValue]]; 
      } 
+0

Спасибо за быстрый ответ! Я не знаком с классом NSPredicate, но я буду изучать его, чтобы узнать больше. Можете ли вы сказать мне, что «SELF MATCHES» должен быть таким образом? И я предполагаю, что materialnumber - это строка, которую я проверяю? Спасибо большое! – Teddy13

+0

yes .. materialnumber - строка и SELF MATCHES правильно. – NHS

+3

Я не знаю, t думаю, что регулярное выражение делает то, что просит OP.Не будет соответствовать 123456, хотя это нормально в случае с OPs? –

0

Используйте следующий код для проверки строки содержат 0-9:

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

Не будет ли это соответствовать 6 раз для строки? «123456», хотя каждая цифра появляется только один раз? –

+0

Спасибо, Дивья, но я считаю, что @ DavidRönnqvist прав. Я не ищу количество цифр в строке, но есть ли какая-либо цифра более 5 раз в этой строке – Teddy13

+0

@ Teddy13 проверьте выше код обновления: –

3

Это не может быть «лучше» способ делать вещи, но это был самый интересный способ сделать это для меня, и это занимает довольно хорошее преимущество фонда с использованием символов наборы, подсчитывали наборы и блок на основе строки перечисления ,

// Your string 
NSString *myString = @"he11o 12345 th1s 55 1s 5 very fun 55 1ndeed."; 

// A set of all numeric characters 
NSCharacterSet *numbers = [NSCharacterSet characterSetWithCharactersInString:@""]; 
NSUInteger digitThreshold = 5; 

// An emtpy counted set 
NSCountedSet *numberOccurances = [NSCountedSet new]; 

// Loop over all the substrings as composed characters 
// this will not have the same issues with e.g. Chinese characters as 
// using a C string would. (Available since iOS 4) 
[myString enumerateSubstringsInRange:NSMakeRange(0, myString.length) 
          options:NSStringEnumerationByComposedCharacterSequences 
          usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) { 
           // Check if substring is part of numeric set of characters 
           if ([substring rangeOfCharacterFromSet:numbers].location != NSNotFound) { 
            [numberOccurances addObject:substring]; 
            // Check if that number has occurred more than 5 times 
            if ([numberOccurances countForObject:substring] > digitThreshold) { 
             *stop = YES; 
             // Do something here based on that fact 
             NSLog(@"%@ occured more than %d times", substring, digitThreshold); 
            } 
           } 
          }]; 

Если вы не позволяете его остановить, то он будет продолжать подсчет числа вхождений для всех цифр в этой строке.

При входе подсчитанное набор выглядит следующим образом (число в квадратных скобках кол):

<NSCountedSet: 0xa18d830> (3 [1], 1 [6], 4 [1], 2 [1], 5 [6]) 
+0

+1 Это похоже на реализацию очень надежных против неизвестных строк-тонкостей. –

+0

+1 Хорошее решение! Спасибо, что поделился – Teddy13

Смежные вопросы