在C中实现(包含)过滤器的最佳方法

时间:2013-04-01 04:20:44

标签: c algorithm

场景如下:我有一个很大的事件清单,我需要解析,只让我传递我需要的事件。实现这一目标的最佳方法是什么?到目前为止我的代码看起来像这样:

#include <stdio.h>
#include <string.h>

int main (int argc, char **argv) {

    int i, j;
    char events[4][15]; /* for the sake of the test only*/
    char *ptr;

    /* probably loaded from a config file */
    const char *filter[] = {"first_event", "third_event"};

    /* just preparing data so far */    
    strcpy(events[0], "first_event");
    strcpy(events[1], "second_event");
    strcpy(events[2], "third_event");
    strcpy(events[3], "foo");

    /* my approach is to have two iterations */
    for (j = 0; j < 2; j++) {
        for (i = 0; i < 3; i++) {
            if (strcmp(filter[j], events[i]) == 0) {
                printf("pass -> %s\n", events[i]);
                continue;
            }
        }
    }
}

2 个答案:

答案 0 :(得分:2)

您不能在C中使用stl map,否则它将是实现m*log(n)总体复杂度的最简单方法,其中m =事件数,n =所有过滤器的最大长度。现在,实现m*log(n)的下一个最简单方法是使用Trie tree。您将找到一个随时可用的trie树实现Here。 该实现的可能用途可能如下所示(我没有尝试编译它):

Trie *ttree = trie_new();

for(i=0; i<numberOfFilter; i++) {
    trie_insert(ttree, filter[i], (void *) 1); //insert your filters in the tree
}

for (i=0; i<numberOfEvents; i++) {
    if (trie_lookup(ttree, events[i]) != TRIE_NULL ) { //check whether i'th event matches with any of the filters
        printf("pass -> %s\n", events[i]);
    }
}

trie_free(ttree);

答案 1 :(得分:1)

“最好的”定义不明确。如果您有大量项目,那么通过使用标准C的 qsort bsearch ,您将看到显着的性能提升,同时最少的复杂性或代码更改。这是非常整洁,但我不知道它是否符合 best 的定义。有关此代码被排除在外的“最佳”定义,请参阅此答案评论:

#include <stddef.h>
#include <stdio.h>
#include <string.h>

int main (int argc, char **argv) {

    int i, j;
    char events[4][15]; /* for the sake of the test only*/
    char *ptr;
    Size_t item_count = 0;

    /* probably loaded from a config file */
    const char *filter[] = {"first_event", "third_event"};

    /* just preparing data so far */    
    strcpy(events[item_count++], "first_event");
    strcpy(events[item_count++], "second_event");
    strcpy(events[item_count++], "third_event");
    strcpy(events[item_count++], "foo");

    qsort(events, item_count, sizeof *events, strcmp);

    for (j = 0; j < 2; j++) {
        char *pass = bsearch(filter[j], events, item_count, sizeof *events, strcmp);
        If (pass != NULL) {
            printf("pass -> %s\n", pass);
            continue;
        }
    }
}