在目标c中比较一个字符串与多个字符串的最优雅/有效的方法?

时间:2012-02-18 22:11:19

标签: objective-c

我有一个字符串(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 个答案:

答案 0 :(得分:6)

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 :(得分:1)

不将标签分成更小的块(例如按长度)或知道匹配参数的确切执行......这是一种非常快速的方法,可以针对特定情况进一步优化:

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;
}

当然,如果您经常这样做,可以将这一功能划分为更优雅。

Rob的答案也很好,但是如果你真的想要最快的话,你需要应用程序执行的上下文。我的方法可能比Rob的快很多倍,或者Rob的速度可能比这种方法快很多倍 - 这取决于执行环境!

答案 2 :(得分:0)

某种散列表,例如NSDictionary或NSHashTable。 [或NSSet。]

(虽然对于一个真正固定的列表,你想要非常有效地搜索基数if梯形图,测试单个字符将是最快的。)