2017-04-09 18 views
-3

if-else-ladderを避けるために、複数の文字列を切り替えるプログラムを作りたかったのです。このように文字列を効率的に切り替える方法はありますか?より効率的なものはありますか?

私の考えは、リンクされたリストを作成し、ある位置で異なるすべてのノードを削除することでした。それから私はそれが何の議論を返して、この番号を切り替えることができます。

私のコード

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

私の質問:これは効率的であるが

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構造体は次のようになりますか?どうすればより効率的にすることができますか?理由はいくつかの愚かな過ち:)

+1

'case 3' - >' case 2'? – BLUEPIXY

+2

'calloc()'を呼び出し、カスタム構造体を使用して3つの文字列の一致を見つける必要がある時点で、あなたは道を離れる。割り当て呼び出しは、おそらく 'strcmp()'を3回呼び出すよりも高価です。とにかく事前割り当て時にリンクされたリストはなぜですか? – dhke

+1

既にスタックにあるデータをリストに再構築するのは非効率的なようです。 – BLUEPIXY

答えて

1

の私は、将来のプロジェクトでこのコードを使用することができ、私はパフォーマンスを失いたくないので、私はおそらく、setようhashtableまたはデータ構造を構築する必要があり、これを知ってほしいですさらにtrie。または少なくともqsortリストを取得し、インデックスを取得するbsearchを実行します。あなたの現在のコードの最大の問題は、あなたが各呼び出しで多くの作業をしているということです。

文字列のリストがコンパイル時にわかっている場合は、gperfで完全なハッシュテーブルを生成することもできます。

GTK+には、GQuarkというデータ型があり、文字列と一意の整数識別子の間に2方向の関連付けができます。

関連する問題