複数の文字列の比較における効果的な手法

このQ&Aのポイント
  • 複数の文字列を比較する際にはstrcmp関数やstrstr関数を使用することが一般的ですが、if文の羅列が長くなってしまうという問題があります。
  • 効果的な手法としては、文字列を照合するためのデータ構造を使用する方法があります。例えば、ハッシュテーブルやトライ木などのデータ構造を使用することで、効率的に文字列を比較できます。
  • これらのデータ構造を使用することで、文字列の比較を簡潔かつ高速に行うことができます。また、プログラムのメンテナンス性を高めることもできます。
回答を見る
  • ベストアンサー

strcmp関数などでの複数の文字列の比較

以下の例はランダムなiの値で文字列にアクセスして その文字列がどの文字列であるかを判定しているプログラムです。 char *string[] = {   "aaa",   "bbb",   "ccc", } ; int i = rand() % 3; if ( strcmp( string[ i ], "aaa" ) == 0 ) {   printf("aaaです"); } if ( strcmp( string[ i ], "bbb" ) == 0 ) {   printf("bbbです"); } if ( strcmp( string[ i ], "ccc" ) == 0 ) {   printf("cccです"); } するとこのようにif文の羅列になってしまいます。 (strstr関数を使う場合などでも同じような感じです。) 複数の文字列を判定する場合などにもっと良い手法は無いでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.4

★追記。 ・指定の文字列を検索して見つかった関数(処理)を実行させます。 ・この場合のサンプルを下に載せます。→前回は『rand() % 3』で直接実行していますが…。 ・関数『FuncAAA()』~『FuncCCC()』と構造体は前と同じです。 サンプル: char *find = "bbb"; ←検索する文字列をセット int i; for ( i = 0 ; Table[i].string != NULL ; i++ ){  if ( !strcmp(find,Table[i].string) ){   Table[i].pfunc(); ←見つかった文字列をここで実行します   break;  } } 最後に: ・文字列が多い場合は、文字列の先頭文字(a-z)をハッシュ・キーとして検索させる方法を取れば  高速になります。または、バイナリ・サーチという方法も有効です。 ・文字列が少ない場合は、上記のサンプルのように for 文でループして比較する方が簡単ですね。 ・以上。おわり。→質問者さんはこちらの『技』が知りたいのでしょう。多分?

amazontester
質問者

お礼

これはすごいです! ちょっと今の私には難しいですが、 頑張ってこの手法を使ってみます。 素晴らしい回答ありがとうございました。

その他の回答 (3)

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.3

★文字列1つに対して1処理(関数)を関連付けるのはどうかな? ・関数のポインタを利用すれば簡単ですよ。 ・下にそのサンプルを載せます。 サンプル: void FuncAAA(void) {  // aaa の処理 } void FuncBBB(void) {  // bbb の処理 } void FuncCCC(void) {  // ccc の処理 } static struct {  char *string;  void (*pfunc)(void); } Table[] = {  "aaa", FuncAAA,  "bbb", FuncBBB,  "ccc", FuncCCC,  NULL, NULL, }; int r = rand() % 3; Table[r].pfunc(); ←この1行で関連付けた関数を実行します 最後に: ・関数に引数を渡したい場合は  『void (*pfunc)(int param,char string);』と宣言して  『Table[r].pfunc(param,string);』として実行します。 ・また、関数に戻り値を追加したい場合は  『int (*pfunc)(void);』と宣言して  『int ret = Table[r].pfunc();』で戻り値を取得できます。 ・戻り値と引数を両方指定することも可能です。 ・以上。おわり。→『Table』の最後の『NULL』行は文字列検索で関数の実行させるために『終端』です。

  • ham_kamo
  • ベストアンサー率55% (659/1197)
回答No.2

switch文を使ってみました。if文の羅列とあまり変わりませんが、string[]の値によってやることが全然違うのであれば、何かしら羅列は必要になるのはしかたがないような気がします。 char *string[] = {   "aaa",   "bbb",   "ccc", } ; int i = rand() % 3; switch (i) {   case 0:     "aaa"のときの処理     break;   case 1:     "bbb"のときの処理     break;   case 2:     "ccc"のときの処理     break;   default:     エラー処理     break; }

amazontester
質問者

補足

すみません。 私が挙げた例だとiの値で上のようにswitchに出来てしまうので 質問の仕方や例のプログラムがやはり悪かったかもしれません。 もし下記のプログラムの様なことをやりたい場合も やはりif文の羅列・・・という感じになってしまうのでしょうか・・。 char string[80]; scanf("%s", string ); if ( strcmp( string[ i ], "aaa" ) == 0 ) {   ;//stringが"aaa"の場合の処理 } if ( strcmp( string[ i ], "bbb" ) == 0 ) {   ;//stringが"aaa"の場合の処理 } if ( strcmp( string[ i ], "ccc" ) == 0 ) {   ;//stringが"aaa"の場合の処理 }

  • herbest
  • ベストアンサー率42% (15/35)
回答No.1

この例ならこれでいいと思うのですが。 int i = rand() % 3; printf("%sです\n", string[i]);

amazontester
質問者

お礼

もしこれが文字列によって全くやることが違うようなケースなら・・ と言う意味で質問させていただきました。 上の例はあくまで例なのでprintfの部分は文字列によって 違うことをやっているとお考えください。

関連するQ&A

  • strcmp

    超C言語初心者です。strcmpを使わずに文字列を比較する文を書いているのですが、途中でわからなくなりました。 宜しければご指摘お願いします。 #include<stdio.h> int main(){ char cp1[100],char2[100]; int i=0; int j=0 printf("1つ目の文字列:\n"); scanf("%s\n",cp1); printf("2つ目の文字列:\n"); scanf("%s\n",cp2); while(cp1[i]=='\0' || cp2[j]=='\0'||cp1[i]==cp2[j]=='\0'){ cp1[i++]; cp2[j++]; } if(cp[i]==cp2[j]=='\0'){ printf("同じ文字数\n); }else if (cp1[i]=='\0'&&cp2[j]!='\0'){ printf("2つ目の方が大きい\n); }else if (cp2[j]=='\0'&&cp1[i]!='\0'){ printf("1つ目の方が大きい\n); } exit(0); } と今書いています。間違いだらけでしょうが、お願いします!!

  • 文字列比較

    最長10文字の文字列を2件入力し、char型の配列にそれぞれ格納する。2つの文字列を比較し、文字列が同じだったら「equal」を表示し異なっていたら「Not equal」を表示するプログラムを作成せよという課題が出ました。 条件として、11文字以上の文字が入力されたら、先頭から10文字までを有効とし、11文字目以降を無視する。下記のプログラムで文字列1に11文字以上入力すると、うまく動きません。なぜ、うまくいかないかと、どうなおしたらよいかを教えてください。 #include<stdio.h> #include<string.h> #define max_length 10 void get_string (char *p_str, int size); int main() { char string1[max_length+2]; char string2[max_length+2]; printf("文字列1:"); get_string(string1,max_length+2); printf("文字列2:"); get_string(string2,max_length+2); if(!strncmp(string1,string2,max_length)) puts("equal"); else puts("Not equal"); } void get_string (char *p_str, int size) { fgets(p_str,size,stdin); }

  • C言語 strcmp 半角スペースがあるとだめ?

    C言語 strcmp 半角スペースが文字列に含まれている場合 文字列の比較がうまくいきません。半角スペースがあると比較できないのでしょうか? プログラム //strcmp #include <stdio.h> #include <string.h> int main(void){ char input[256]; char str[] = "HelloWorld!";   //char str[] = "Hello World!";だとうまくいかない。 printf("%s\n>", str); scanf("%s", input); if ( strcmp(input, str) == 0){ printf("同じです。\n"); }else{ printf("違います。\n"); } return 0; }

  • 文字列の比較

    文字列の比較の仕方がよくわかりません。strcmpコマンドを使わずにできるだけ簡単にかく方法を教えてください。途中までは書きます。for分とかを使うんでしょうか? #include <stdio.h> int main(void) { char SpelA[] = "dog"; char SpelB[] = "dogfood" ; int long ; long = 1 ; if (long == 1) { printf("Good!\n") ; } ; return 0 ; } ;

  • 関数の作り方

    文字列s1に文字列s2が含まれるか判定する関数search を作りたいのですが、コンパイルできません。 どこに問題がありますか?? #include<stdio.h> #include<string.h> int seach(char *s1,char *s2) { char *p; p = strstr(s1,s2); if(p == NULL){ return 0; }else{ return 1; } } main(void){ char s1[255]; char s2[255]; int res; printf("文字列s1を入力:"); scanf("%s",s1); printf("文字列s2を入力:"); scanf("%s",s2); res = search(s1,s2); if(res == 1){ printf("文字列s1に文字列s2が含まれます\n"); } if(res == 0){ printf("文字列s1に文字列f2は含まれません\n"); } return 0; }

  • 文字列の並び替えについて。

    #include<stdio.h> #include<string.h> main() {char name[40][50]; int i; for(i=1;i<=;i++){ printf("名前="); gets(name[i]); } if(strcmp(name[1],name[2])>0){ printf("%s %s \n",name[2],name[1]);} if(strcmp(name[1],name[2])<0){ printf("%s %s \n",name[1],name[2]);} if(strcmp(name[1],name[2])==0){ printf("%s %s \n",name[1]);} } は二人の名前を早い順に並べ替えるものなんですが、これを五人の名前を並べ替えるものにしたいので、どのようなプログラムにしたらいいのか教えてください。

  • 文字列処理関数について

    おみくじのプログラムを書きました。初めのが私のもので、次のが参考書のものなのですが、なんでわざわざ 文字列処理関数を使うのかがわかりませんでした。 教えてください!! int main() {   int r =0;   int i =0;   srand(time(NULL));   r = rand()%3+1;   for(i=0;i<2;i++){    if(r == 1)    {  printf("大吉:充実した1日\n");    }    else if(r == 2)    {  printf("小吉:充実した1日\n");    }    else    {       printf("凶:衝動買いに注意\n");    }    return 0; } ********************** ********************** main(){     int kuji;     char kekka[6];     char str[45];     srand(time(NULL));     r = rand()%3+1;     switch(kuji){     case 1:           strcpy(kekka,"大吉");         strcpy(str,"金運アップ");         break;    /*case2,3は省略します*/           default:    break; } printf("%s:%s",kekka,str); return 0; }

  • toupper関数とstrcmp関数を使った問題

    前回答えてくださった方々へのお礼 ・前回質問した際、質問に答えてくださった方々、皆様のおかげで問題を解く事ができました。本当にありがとうございました。 ↓ここから質問です。 「end」と入力されるまで、キーボードから文字列を読み取るプログラムを作成してください。ただし、大文字と小文字が混ざった「EnD」などでも終了するようにしてください。小文字を大文字に変換する「toupper( )関数」を利用してください。また、文字列の比較には「strcmp( )関数」を利用してください。 という問題を解いているのですが、自分でした結果 #include <stdio.h> #include <ctype.h> #include <string.h> int main(void) { char str[10]; ←str[10]は適当に値を決めているだけです int i,ret; int result; do { printf("文字列を入力してください:"); scanf("%s", str); i = 0; while (str[i] != ???? ) // 文字列の最後かチェック { ret = toupper(?); // toupper関数に1つずつ渡す i++; } result = strcmp("END", str); //文字列の比較 if (result == 0) { break; //ループを抜ける! } } while (1);            // 条件が1の場合は永久ループ return 0; } ここまではできたのですが、どうしても while (str[i] != ???? ) // 文字列の最後かチェック { ret = toupper(?); // toupper関数に1つずつ渡す i++; } この部分の「?」と書いている部分がわかりませんでした。 わかる方が居られましたらどうか教えてもらえないでしょうか? あと、おかしな部分等がありましたら教えてください。 どうかよろしくお願いします。

  • strstrを利用しない文字列検索について

    キーボードから入力した文字列 str に対し, This is~の文字列中に str が出現するかどうかを判定して表示するプログラムを作成したいのですが、うまくコンパイルができません。 条件ですが、、、 ・forループを利用し、0文字目、1文字目と順に検索していく ・strstr関数およびstring.hを利用しない です。このプログラムをいじって教えてほしいです。 ややこしくて答えづらい質問かと思いますが、有識者の知恵を拝借したいです。よろしくお願いします。 #include <stdio.h> int main(void) { char str[256]; char s[] = "This is a pen. That is an apple."; int i,j,k,checker; printf("This is a pen. That is an apple.\n\n"); gets(str); for(j=0;j<256;j++) { for(i=j,k=0;str[k]!='\0';k++,i++) { if(str[k]==s[i]) { checker=1; } else { checker=0; } } } if(checker==0) { printf("NG!その文字列は含まれていません。\n"); } else { printf("OK!その文字列は含まれています。\n"); } }

  • read()で読みこんだ文字列の比較について

    実行環境はLinuxで、ディストリビューションはturboLinuxです。 strcmpで文字列の比較ができるのですが、何故かreadで読み込んだ文字列は比較できません。 何故なのでしょうか。ちなみにコードは下です read(sock_ipadrc,&Buf,sizeof(Buf)); if(!strcmp("GETADR",Buf)){ printf("等しい"); }