- ベストアンサー
C言語プログラミングについて
- C言語で車の順位を更新するプログラムを作成する方法について教えてください。
- プログラムでは、1〜20のナンバーを持つ20台の車が200周の耐久レースを行います。一周するごとにランダムに選ばれた車が1〜6のランダムな数字の数だけ順位を上げます。
- グローバル変数やポインタは使用せずに、if文、for文、while文、配列のみを使用してプログラムを作成してください。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
まずswapを使ってup_rankしているのが問題。かなり無駄。 swapは「2つの変数の入れ替え」ですが、それは「m位の車が1台抜く」のと同じ。 ・m位が1台抜く処理 c = m位 m位 = m-1位 m-1位 = c ・swap関数の中身 int c = *a; *a = *b; *b = c; どうです?同じでしょ? じゃあ「m位の車が3台抜く」の場合は? m位より上の3台を順に下にズラせば良いから c = m位 m位 = m-1位 m-1位 = m-2位 m-2位 = m-3位 m-3位 = c でオッケー。 「swapの真ん中の1行」が3行に増えただけの話。 例えば、10位の車が4台抜いて6位に上がった場合 10位のナンバーを変数cに格納(10位が上書き可能になる) 9位のナンバーを10位に格納(9位が上書き可能になる) 8位のナンバーを9位に格納(8位が上書き可能になる) 7位のナンバーを8位に格納(7位が上書き可能になる) 6位のナンバーを7位に格納(6位が上書き可能になる) 変数cを6位に格納 と言う処理で済む。 これなら「関数にするまでもない」ので、グローバル変数もポインタも不要で書ける。forループを1行書くだけ。 この問題の「ただしグローバル変数、ポインタは使わずif,for,while,配列のみで書くこと」と言う条件は、上記のような「forループを1行書くだけ」と言う事に気付けるかどうかが題意だと思う。 int j,c,m,n; (略) /*ます、抜く台数を決めて*/ n = my_rand(6) + 1; /*その後で、車を選んで、有り得ない車を選んだら選び直す*/ do { m = my_rand(20); } while (m >= n); (略) /*順位入れ替え*/ for (c = car[m],j = m;j > m - n;j--) car[j - 1] = car[i]; car[m - n] = c; あと、表示の前にmとnの整合性チェックをして選び直ししないと「1位の車が2台抜く」とかっていう、有り得ない表示が出ちゃうので注意(質問者さんの元のプログラムだと、mがマイナスにならないようにbreakしては居るけど、表示が変になる)
その他の回答 (4)
- asuncion
- ベストアンサー率33% (2127/6289)
swap関数で行なっている処理を、直接up_rank関数の中に書く、という手はどうですか? 要するに、a[m]とa[m+1]とが入れ替わればいいんですよね。
> そうですね。swap関数のところの*の話だと思います。 > でも単に外しただけだと、動くけど順位は変動しないんですよね・・・ swap関数をmy_rand()のようにマクロにすれば良いかと。
- kmee
- ベストアンサー率55% (1857/3366)
あ、もしかしたら、ポインタ使わずに swap(&a[m], &a[m + 1]); ではなく swap(a,m,m+1); の様に、しろって意味かもしれません。 (ポインタ使ってるけど)
補足
遅くなりましたが、回答ありがとうございます。 そうですね。swap関数のところの*の話だと思います。 でも単に外しただけだと、動くけど順位は変動しないんですよね・・・
- kmee
- ベストアンサー率55% (1857/3366)
"[%2d] %d\n"とか"pause"とかの文字列リテラルを使っている以上、「ポインタを使わず」は無理 .... という屁理屈はともかく。 > up_rank(car, m, n); ここに、up_rank関数の内容を埋め込めばいいのでは? 仮引数のaではなく、実際のcarにするとかして。 swapも同様にswap関数の中身を埋め込んで。 ついでに、print関数も引数にポインタが使われてますから、mainに埋め込む必要がありますね。 細かいところで修正した方がいい箇所はあります。 ※ 周回数の200、配列サイズの20を直接書いてるのを、変数やマクロを使うようにする、とか が、件の条件が無ければ、それ以外は今のプログラムの方がいいと思います。
お礼
丁寧な解説ありがとうございます。 おかげさまで、条件に合った、納得のいくプログラムを書くことができました。