• ベストアンサー

文字列 ポインタ

3つの文字ポインタを作成し,最初のポインタが「one」を,二番目のポインタが「two」を,三番目のポインタが「three」をさすように初期化するプログラムを作成しなさい.次にこれらの3つの文字列の順列をすべてプログラムに表示させなさい. という問題で順列をうまく並べる方法がわかりません.手打ちでprintを6個作ることはできますが... うまい方法があるかないか,どのような方法か教えてください.よろしくお願いします. #include<stdio.h> int main(void) { char *a,*b,*c,*t; int i; a="one"; b="two"; c="three"; printf("%s\t%s\t%s\n",a,b,c); return 0; }

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

  • ベストアンサー
回答No.1

プログラムが今後どう発展するかによりますが、扱う文字列の数が増えるなら手書きはありえない選択肢です。 まず考えるのは再帰呼び出しするというアプローチだと思います。 文字列から一つ選び、それを使ったことを記録しつつ、自分自身を再帰呼び出しします。そして、全部の文字列を選び終わったら表示をします。選ぶ文字列を順繰りに変えて再帰呼び出しをすることで順列を表示できるでしょう。 このアプローチでは、入力として最低でも次のものを取るでしょう。 - 未使用の文字列 (あるいは、既にどの文字列を使ったか) のリスト - 表示する文字列の中間結果 という方針でちょっと書いてみました。効率は多少悪い気がしますが... C言語では標準の機能としてリスト操作が無いので、未使用の文字列を覚えておく方法ではなく、既に使った文字列のインデックスを覚えておくという方法で実装しました。具体的には、使用した場合はused[インデックス]にtrueを入れて、使用済みであることを示します。 また、表示する文字列の中間結果についてもプログラムの最初にその領域を確保して、使っていくという実装になっています。to_print配列に表示する文字列のインデックスを覚えておき、次に値を入れるto_print配列の位置をnextで示します。 #include <stdbool.h> #include <stdio.h> void print_strs(char *str[], size_t to_print[], size_t next, bool used[], size_t len) { size_t i; if (next == len) { for (i = 0; i < len; i++) { printf("%s ", str[to_print[i]]); } printf("\n"); } for (i = 0; i < len; i++) { if (used[i] != true) { to_print[next] = i; used[i] = true; print_strs(str, to_print, next + 1, used, len); used[i] = false; } } } int main(void) { char *str[] = {"one", "two", "three", "four", "five", "six", "seven"}; size_t len = sizeof(str) / sizeof(str[0]); size_t to_print[len]; bool used[len]; size_t i; for (i = 0; i < len; i++) { used[i] = false; } print_strs(str, to_print, 0, used, len); return 0; } 一応、FreeBSD 8.3のgccで特にオプションを付けずにコンパイル、実行できることを確認しています。

masics
質問者

お礼

どうもありがとうございました.