2014-01-15 5 views
2

структур Есть ли способ реализации «LookupFunc» в этом коде:Простой поиск по ключу для

enum FoodType { FRUIT, VEGGIE, DESSERT }; 

struct Food { 
    char name[20]; 
    int index; 
    FoodType type; 
}; 

struct Food APPLE = {"apple", 0, FRUIT}; 
struct Food CARROT = {"carrot", 1, VEGGIE}; 
struct Food CANDY = {"candy", 2, DESSERT}; 


struct Food f = LookupFunc("apple"); 
printf("indexof apple: %d\n", f.index); 
printf("type of apple: %d\n", f.type); 

у меня будет только 8 типов объектов Food/структур, но неограниченные возможности для поиска. В идеале, имя char [20] не понадобилось бы в моей структуре, и это могло бы идти по имени переменной, но я не думаю, что C может это сделать. У меня такое чувство, что это может быть проще, используя многомерные массивы и поиск с использованием цикла for.

+0

Не должно быть 'struct Food APPLE ...' вместо 'struct Opcode APPLE ...'? –

+0

Да, жаль, что я исправил его сейчас – ParoX

+0

Ваша интуиция в порядке - C не сохраняет имена переменных или полей во время выполнения, поэтому вам нужно будет позаботиться о сохранении ваших значений в структурах данных, которые позволят вам искать впоследствии. Единственное, что я хотел бы добавить, это то, что вы можете захотеть использовать перечисление для имен/категорий переменных вместо строк. – hugomg

ответ

1

Сделать массив struct Food как это:

#define MAX_FOODS (8) 
struct Food foods[MAX_FOODS] = { 
            {"apple", 0, FRUIT}, 
            {"carrot", 1, VEGGIE}, 
            {"candy", 2, DESSERT}, 
            ... 
           }; 

Таким образом, это будет легко найти и проиндексировать.

int i = LookupFunc("apple"); 

int LookupFunc(char *str) 
{ 
    for(int i = 0; i < MAX_FOODS; i++) 
    { 
     if(strcmp(foods[i].name, str) == 0) 
      return i; 
    } 

    return -1; // Not found 
} 
+0

Обход массива, лучший вариант здесь, учитывая только 8 записей, не стоит искать более быстрые бинарные методы дерева/хеш-таблицы? – ParoX

+0

@BHare Да, если массив становится достаточно большим, следует использовать другой метод поиска. –

1

Та же самая идея как ответ пустячный BITS, но с менее жесткого кодирования

//define constant lookup table 
const struct Food foodTable[] = { 
    APPLE, CARROT, CANDY, 
}; 
const int foodTable_len = sizeof(foodTable)/sizeof(Food); 

Food LookupFunc(const char *foodStr) { 
    for (int i=0; i<foodTable_len; i++) { 
     bool strMatch = 0 == strcmp(foodTable[i].name, foodStr); 
     if (strMatch) 
      return foodTable[i]; 
    } 

    //no match. Return something invalid 
    return ?; 
} 

Кроме того, для реализации эффективной, большой, только для чтения карты, можно сделать хэш-таблицу и использовать идеальный (беспощадная) хэш-функция. См. Раздел внешних ссылок на wikipedia page

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