самый элегантный / эффективный способ сравнить одну строку со многими в цели c? - PullRequest
1 голос
/ 19 февраля 2012

У меня есть строка (tagName), и я хочу выяснить, соответствует ли она какой-либо из следующих строк.Какой самый лучший / самый эффективный способ сделать это?Использовать массив и перебрать его?Или это безобразный способ?

if ([tagName isEqualToString:@"a"] ||
            [tagName isEqualToString:@"dd"] ||
            [tagName isEqualToString:@"li"] ||
            [tagName isEqualToString:@"span"] ||
            [tagName isEqualToString:@"br"] ||
            [tagName isEqualToString:@"b"] ||
            [tagName isEqualToString:@"big"] ||
            [tagName isEqualToString:@"em"] ||
            [tagName isEqualToString:@"i"] ||
            [tagName isEqualToString:@"u"] ||
            [tagName isEqualToString:@"small"] ||
            [tagName isEqualToString:@"strong"] ||
            [tagName isEqualToString:@"sub"] ||
            [tagName isEqualToString:@"sup"] ||
            [tagName isEqualToString:@"ins"] ||
            [tagName isEqualToString:@"del"] ||
            [tagName isEqualToString:@"code"] ||
            [tagName isEqualToString:@"kbd"] ||
            [tagName isEqualToString:@"samp"] ||
            [tagName isEqualToString:@"tt"] ||
            [tagName isEqualToString:@"var"] ||
            [tagName isEqualToString:@"pre"] || 
            [tagName isEqualToString:@"abbr"] ||
            [tagName isEqualToString:@"center"] ||
            [tagName isEqualToString:@"acronym"] ||
            [tagName isEqualToString:@"address"] ||
            [tagName isEqualToString:@"bdo"] ||
            [tagName isEqualToString:@"blockquote"] ||
            [tagName isEqualToString:@"q"] ||
            [tagName isEqualToString:@"cite"] ||
            [tagName isEqualToString:@"img"] ||
            [tagName isEqualToString:@"p"] ||
            [tagName isEqualToString:@"s"] ||
            [tagName isEqualToString:@"font"] ||
            [tagName isEqualToString:@"strike"] ||
            [tagName isEqualToString:@"caption"] ||
            [tagName isEqualToString:@"th"] ||
            [tagName isEqualToString:@"tr"] ||
            [tagName isEqualToString:@"td"] ||
            [tagName isEqualToString:@"thead"] ||
            [tagName isEqualToString:@"tbody"] ||
            [tagName isEqualToString:@"tfoot"] ||
            [tagName isEqualToString:@"col"] ||
            [tagName isEqualToString:@"colgroup"] ||
            [tagName isEqualToString:@"dfn"]
            ) {

Ответы [ 3 ]

6 голосов
/ 19 февраля 2012
static dispatch_once_t once;
static NSSet *htmlTags;
dispatch_once(&once, ^{
    htmlTags = [NSSet setWithObjects:
        @"dd", @"li", @"span",
        @"br", @"b", @"big",
        // etc.
        nil];
});

if ([htmlTags member:tagName]) {
    NSLog(@"Found it!");
}
1 голос
/ 19 февраля 2012

Без разделения тегов на более мелкие порции (например, по длине) или без знания точного выполнения параметров соответствия ... вот один очень быстрый подход, который может быть дополнительно оптимизирован для конкретных случаев:

bool IsTag(NSString * tagName) {
    const size_t NTags = 45;
    NSString * const tags[NTags] = {
        @"a", @"dd", @"li", @"span", @"br", @"b", @"big", @"em", @"i", @"u",
        @"small", @"strong", @"sub", @"sup", @"ins", @"del", @"code",
        @"kbd", @"samp", @"tt", @"var", @"pre", @"abbr", @"center", @"acronym",
        @"address", @"bdo", @"blockquote", @"q", @"cite", @"img", @"p", @"s",
        @"font", @"strike", @"caption", @"th", @"tr", @"td", @"thead", @"tbody",
        @"tfoot", @"col", @"colgroup", @"dfn"
    };

    /* pointer comparison will be effective if @a tagName may be derived
       from a literal (or a copy of a literal):
    */
    for (size_t idx = 0; idx < NTags; ++idx) {
        if (tags[idx] == tagName) {
            return true;
        }
    }

    /* no match yet - perform character comparison: */
    for (size_t idx = 0; idx < NTags; ++idx) {
        if ([tags[idx] isEqualToString:tagName]) {
            return true;
        }
    }

    return false;
}

Конечно, вы можете разделить эту функцию, чтобы сделать использование более элегантным, если вы обнаружите, что делаете это часто.

Ответ Роба также хорош, но вам нужно применить контекст выполнения вашей программы, если вы действительно хотите быстрее. Мой подход может быть во много раз быстрее, чем у Роба, или Роб может быть во много раз быстрее, чем этот подход - это зависит от контекста выполнения!

0 голосов
/ 19 февраля 2012

Какой-то тип хеш-таблицы, такой как NSDictionary или NSHashTable.[Или NSSet.]

(Хотя для действительно фиксированного списка, который вы хотите искать очень эффективно, радикальная if лестница тестирует отдельные символы, будет быстрее всего.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...