2017-04-09 60 views
-3

我想製作一個程序來切換多個字符串以避免if-else-ladder。這種切換字符串的方式是否有效?有更有效的嗎?

我的想法是創建一個鏈表並刪除每個在某個位置上不同的節點。然後,我可以只返回它是什麼參數,並切換這個數字。

我的代碼

int str_switch(char* query, int arg_count, ...) { 
    //Variables 
    int i, j; 
    struct node* args = (struct node*)calloc(arg_count, sizeof(struct node)); 
    va_list list; 

    //va_list -> array 
    int start = 0; 
     //data 
    va_start(list, arg_count); 
    for (i = 0; i < arg_count; i++) { 
     args[i].data = va_arg(list, char*); 
     args[i].prev = i - 1; 
     args[i].next = i + 1; 
    } 
    va_end(list); 
     //start 
    args[0].prev = -1; 
     //end 
    args[arg_count - 1].next = -1; 

    //switch 
    int len = strlen(query); 
    for (i = 0; i <= len; i++) { //i <= len: null character is also compared 
     for (j = start; j != -1; j = args[j].next) { 
      //remove from list 
      if (*(args[j].data + i) != *(query + i)) { 
       //only one element in list 
       if (args[j].prev == -1 && args[j].next == -1) { 
        start = -1; 
       } 
       //first element 
       else if (args[j].prev == -1) { 
        start = args[j].next; 
        args[start].prev = -1; 
       } 
       //last element 
       else if (args[j].next == -1) { 
        args[args[j].prev].next = -1; 
       } 
       //mid element 
       else { 
        args[args[j].prev].next = args[j].next; 
        args[args[j].next].prev = args[j].prev; 
       } 
      } 
     } 
    } 

    //return 
    free((void*)args); 
    return start; 
} 

node結構是這樣的:

struct node { 
    int next; 
    int prev; 
    char *data; 
}; 

小測試程序:

#include<stdio.h> 
#include<stdlib.h> 


int main(void){ 
    char query[10] = "Horse"; 
    switch(str_switch(query, 3, "Bird", "Dog", "Horse")) { 
     case 0: // Bird 
      printf("It\'s a bird\n"); 
      break; 
     case 1: // Dog 
      printf("It\'s a dog\n"); 
      break; 
     case 3: // Horse 
      printf("It\'s a horse\n"); 
      break; 
     case -1: // Error 
      printf("It\'s an error :(\n"); 
      break; 
     default: // ? 
      printf("It\'s nothing..?\n"); 
      break; 
    } 
    system("pause"); 
    return 0; 
} 

我的問題:是這有效嗎?我怎樣才能讓它更有效率?我想知道這是因爲我可以用在未來的項目中的代碼,我不希望失去因爲一些愚蠢的錯誤:)

+1

'案例3' - >'案例2'? – BLUEPIXY

+2

在您需要調用'calloc()'並使用自定義結構來查找三個字符串匹配的位置時,您將無法跟蹤。分配調用可能比調用三次strcmp()更昂貴。爲什麼預先分配鏈接列表,無論如何? – dhke

+1

將堆棧中已有的數據重建爲列表似乎效率不高。 – BLUEPIXY

回答

1

你或許應該建立一個數據結構就像一個set,一個hashtable或性能甚至是trie。或至少qsort的名單,並做bsearch獲得索引。您當前的代碼中最大的問題是您在每次調用時都要做很多工作。

如果你的字符串列表在編譯時已知,你甚至可以用gperf生成一個完美的哈希表。

另一種可能性是GTK+,它有一個GQuark數據類型,它爲您提供了一個字符串和唯一整數標識符之間的雙向關聯。

相關問題