ページ 11

課題に取り組んでいるんですが

Posted: 2010年7月04日(日) 20:25
by 南瓜
いつもお世話になってます。今回は大学の課題の添削、完成を手伝って下さい

上に元となるプログラムと問題文と出来た課題1と3があります。
問い1と3は出来たので、こうした方が見易いなどがありましたらコメントお願いします
問い2と4は別に表示します。
今回期限がありまして、7/7までと短いですが協力お願いします。

また、http://www.play21.jp/board/formz.cgi?ac ... &rln=55785
でもポーカーを作っている途中なので、何か間違っている点などがありましたらご指摘お願いします

Re:課題に取り組んでいるんですが

Posted: 2010年7月04日(日) 20:32
by パコネコ
()

Re:課題に取り組んでいるんですが

Posted: 2010年7月04日(日) 20:35
by 南瓜
新規投稿のやり方が少し変わったのかな?

問い2は、区間を10個に割るっていうのがうまく出来ません
あれだと単に1を10で割っただけになっているので…

問い4は、2次元格子を作って、原点を設置する所が出来ません
それが出来れば方向を選ぶ所は出来たので、up++;やdown++;も追加すれば
進むプログラムが出来るかな?

Re:課題に取り組んでいるんですが

Posted: 2010年7月04日(日) 20:37
by シエル
前から南瓜さんが添付するファイルは何故か文字化けしています。
ポーカーのやつもです。。。
文字コードの問題ですかね? 画像

Re:課題に取り組んでいるんですが

Posted: 2010年7月04日(日) 20:41
by パコネコ
問題書いてもらってもいいですか?

Re:課題に取り組んでいるんですが

Posted: 2010年7月04日(日) 20:42
by スキマ妖怪
エンコードをUnicodeに変えれば文字化けしませんよ。

追記-----------------------------------------

短すぎて訳が分からないな…orz

IEの設定の話です。
ちなみにFireFoxでは、ちゃんと見れました。
画像

Re:課題に取り組んでいるんですが

Posted: 2010年7月04日(日) 20:44
by 南瓜
肝心な問題文が文字化け起こしてる…なんで?

問い1 rand関数を使って上記の方法を得られる乱数の平均値を出してみよう。乱数の個数が10,100,1000個の場合の平均値を求める
問い2 0から1までの区間を10個に割り、乱数がどの区間に入るか数えるプログラムを作る。乱数の個数が10,100,1000個の場合どうなるか
グラフはエクセルなどを使って描くこと
問い3 乱数を使って、1から4までの数をランダムに出すプログラムを作れ
問い4 2次元上の格子において、原点から進む方向は東西南北の4通りとして、4つの方向から1つをランダムに選び、進むプログラムを作れ
通った点をエクセルなどを使ってプロットしなさい。また、乱数の個数が10,100,1000個の場合どうなるか

Re:課題に取り組んでいるんですが

Posted: 2010年7月04日(日) 20:46
by Dixq (管理人)
すみません、今時間が無くて回答は出来ないのですが、Shift-Jis版だけアップします。

Re:課題に取り組んでいるんですが

Posted: 2010年7月04日(日) 21:04
by パコネコ
これ数えるんですよね
問いの2
1~10にしたからダメかな?
#include<stdio.h>//使えるかな?
void main(void){
int x[10],n,a;
int cot;

scanf("%d",&n);
for(a=0;a<n;a++){
cot=rand()%10;
x[cot]++;
}
for(a=0;a<10;a++)
printf("%d \n",x[a]);
}
結構はしょった上に1~10だからダメかな?
=================
つづり間違えたから直します
forの中も… 画像

Re:課題に取り組んでいるんですが

Posted: 2010年7月04日(日) 21:18
by スキマ妖怪
0.0 ~ 1.0 の範囲でどの区間に属しているか、だから端折っちゃダメだと思いますよ。

int interval[10] = {0};

for (i = 0; i < n; i++) {
x = rand()/(RAND_MAX + 1.0);
printf("i = %d rand = %f \n", i, x);
if( x >= 1.0 ) // 1.0のとき10倍すると範囲外になる
interval[9] ++;
else
interval[x * 10] ++;
}

とか?
(間違っているかもしれませんが…)

Re:課題に取り組んでいるんですが

Posted: 2010年7月04日(日) 21:28
by パコネコ
> rand()/(RAND_MAX + 1.0);
これが0~1.0の式だと思ってもいいですか?
なんかよく見かけるし。
勉強不足ですいません

Re:課題に取り組んでいるんですが

Posted: 2010年7月04日(日) 21:40
by パコネコ
#include<stdio.h>//使えるかな?
void main(void){
int x[11],n,a;
int cot;

scanf("%d",&n);
for(a=0;a<n;a++){
cot=rand()%10/10;//これなら0~1
x[cot*10]++;
}
x[9]+=x[10];
for(a=0;a<10;a++)
printf("%d \n",x[a]);
}
コメントはまたはしょったけど…0~1にはなったと思う
=================
>cot=rand()%11/10;//これなら0~1
画像

Re:課題に取り組んでいるんですが

Posted: 2010年7月04日(日) 22:04
by 南瓜
返信ありがとうございます。

元になるプログラムでfor(i = 0; i <=n; i++) {
で<じゃなくて<=なのも気になるし
(RAND_MAX + 1.0)を追加するのもよく判りません…
でも確かにRAND_MAX~はよく見かけますよね

とりあえず、区間を10個に割るのは配列を使えばいいのかな?

Re:課題に取り組んでいるんですが

Posted: 2010年7月04日(日) 22:14
by スキマ妖怪
> cot=rand()%10/10;//これなら0~1

これだと

0.0, 0.1, 0.2, ... , 0.9 の10種類の数しか表わせないと思うのですが…
実際には、もっともっと細かいですよね、例えば 0.0001, 0.141592 とか

件の
rand()/(RAND_MAX + 1.0);
は、

RAND_MAX = 0x7FFF = 32767
rand() の最大値もRAND_MAX なので、

(0から32767までの数) / 32768

という式になり、計算すると0.0~1.0になると思います。
(あまり細かい数はこれでも現せないですが、課題だししょうがないですよね;)


(…と書いてるうちによく分からなくなってきた;)

Re:課題に取り組んでいるんですが

Posted: 2010年7月04日(日) 22:14
by 白い時空
あの、
rand()/(RAND_MAX + 1.0)の値ですが、
正確には0以上1未満です。1にはなりません。

なぜならrand()がRAND_MAXになったとしても
RAND_MAX/(RAND_MAX + 1.0)ですから。

あと、気付いたところですが

スキマ妖怪さんのソ-スでは
interval[x * 10]++;としていますが、キャストして
interval[(int)(x * 10)]++;とするべきですね。

パコネコさんのソースでは
rand()%10/10;としていますが、これでは
0, 0.1, 0.2, 0.3,… 0.9の10個しか出ません。
また、スキマ妖怪さんと同様キャストをしてないです。

Re:課題に取り組んでいるんですが

Posted: 2010年7月04日(日) 22:21
by パコネコ
残念だけどその通りですね。
小数点以下2位より下は考えていませんでした。
/*
rand()/(RAND_MAX + 1.0)の値ですが、
正確には0以上1未満です。1にはなりません。
*/
覚えておきます。
勉強になりました。ありがとうございました。
>キャスト
(int)のことですか?具体的な意味知らなくて…だいたい後のものを整数型として計算するみたいな感じですか?

Re:課題に取り組んでいるんですが

Posted: 2010年7月04日(日) 22:38
by スキマ妖怪
> rand()/(RAND_MAX + 1.0)の値ですが、
> 正確には0以上1未満です。1にはなりません。

そうですよね。
0から1以下(1を含むと)勘違いしていました、
実際は0から1未満ですよね(^^;
No:55964 を書いた後に気付きましたorz


キャストについても、うっかりしていてコンパイルして確認してませんでした…
今後、こういうすぐ分かるようなミスはなくしていきたいです;

Re:課題に取り組んでいるんですが

Posted: 2010年7月05日(月) 01:34
by パコネコ
一番1に近くなるのは
rand()がRAND_MAXのときですよね。
1にはなりませんが一番近いということで
/*
rand()/(RAND_MAX + 1.0)の値ですが、
正確には0以上1未満です。1にはなりません。

なぜならrand()がRAND_MAXになったとしても
RAND_MAX/(RAND_MAX + 1.0)ですから。
*/
a=rand();
if(a==RAND_MAX)
a=1.0;
else
a=a/(RAND_MAX+1.0)
今度こそ、これなら1になりますよね。

Re:課題に取り組んでいるんですが

Posted: 2010年7月05日(月) 02:05
by フリオ
 
 問3、4の答えで、rand() % 4 + 1 としていますが、それまでの流れを踏襲しなくていいのでしょうか?
 
 この問題は、問2で考えた rand() / (RAND_MAX + 1.0) で得られた 0~1未満 の乱数を
0~9 の整数に置き換える方法を使って 1~4 の整数を求めさせたいのではないのでしょうか。


 問4は、とおった点をエクセルなどを使ってプロットしなさい とあるので、
単に方向を表示するだけではなく軌跡を保存する必要があります。

進む方向は、配列を使って、

int step[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};

等としたほうが、見通し良くなります。
画像

Re:課題に取り組んでいるんですが

Posted: 2010年7月05日(月) 02:13
by フリオ
>a=rand();
>if(a==RAND_MAX)
> a=1.0;
>else
> a=a/(RAND_MAX+1.0)
>今度こそ、これなら1になりますよね。


なら、
a = rand() / (double)RAND_MAX;
でいいです。

Re:課題に取り組んでいるんですが

Posted: 2010年7月05日(月) 16:10
by パコネコ
要は1.0をたすことによって1にならないようにしていたんですね。
まだうまく理解してなくて…ありがとうございます。また少し理解できました。

Re:課題に取り組んでいるんですが

Posted: 2010年7月05日(月) 20:17
by 南瓜
random = (rand()/(RAND_MAX + 1.0)) % 4 + 1;とすると
invalid operands to binary %というエラーた出てしまうので
random = rand() % 4 + 1;にしました

Re:課題に取り組んでいるんですが

Posted: 2010年7月05日(月) 20:22
by パコネコ
invalid operands to binary %=無効なオペランドの 2 つのバイナリ %
意味は知りませんけど…小数点以下は無視していいんですか?
(問いの3番の場合問題文には指定ないけど…4番の問題があるから大丈夫だと思いますが…)

Re:課題に取り組んでいるんですが

Posted: 2010年7月05日(月) 23:50
by 白い時空
たしか、%は整数にしか使えないはずです。
double型にはmath.hのfmod関数を使います。

問3ですが、よく見たら1から4までの数と書いてあるだけで
整数と小数どちらを出せばいいか書いてないですね。

1から4までの整数なら
random = rand() % 4 + 1
でOKですが、1から4までの小数を出すなら
random = (rand()/RAND_MAX) * 3 + 1;
です。(1.0を外したので4も出ます)

Re:課題に取り組んでいるんですが

Posted: 2010年7月06日(火) 00:26
by フリオ
>問3ですが、よく見たら1から4までの数と書いてあるだけで
>整数と小数どちらを出せばいいか書いてないですね。
 
 問4に"4つの方向から1つをランダムに選び"とあるので、
そこに誘導する問題として 1~4 の整数ではないでしょうか。
 

Re:課題に取り組んでいるんですが

Posted: 2010年7月06日(火) 00:43
by へろりくしょん
>でOKですが、1から4までの小数を出すなら
>random = (rand()/RAND_MAX) * 3 + 1;

整数同士の四則演算はどこまでいっても整数ですから、((double)rand()/RAND_MAX)とかするなりしないと小数は得られませにょ。

Re:課題に取り組んでいるんですが

Posted: 2010年7月06日(火) 00:52
by 白い時空
ああ、double型へのキャストを忘れてました。すいません。
C言語はこういうことが不便ですよね。

1から4までの小数は問題に指定がなかったので、参考までに書いてみただけです。

Re:課題に取り組んでいるんですが

Posted: 2010年7月06日(火) 14:09
by 南瓜
問い4一応形?になりました
これだと原点から移動した位置は判るんですが
これを元にエクセルで描くとなると出来るのかな?

Re:課題に取り組んでいるんですが

Posted: 2010年7月06日(火) 14:15
by パコネコ
移動させるごとにファイルに保存でもします?
西東北西みたいな
=================
西 東 北 西
エクセルって拡張子いりましたっけ?txtでいいのかな? 画像

Re:課題に取り組んでいるんですが

Posted: 2010年7月06日(火) 14:26
by fatens
for 文の中で座標をコンマ区切りで出力します。
printf("%d,%d\n", x, y);
実行するときに、a.exe > a.csv とリダイレクトして、
csvファイルをエクセルで開き、あとは散布図にして適当に軸を設定する、
というのはどうでしょうか。
画像

Re:課題に取り組んでいるんですが

Posted: 2010年7月06日(火) 14:55
by 南瓜
kadai4 a.exe > a.csvとしてエクセルで開いたら
図のような文字化けを起こしました
文字コードが悪いのかな?

Re:課題に取り組んでいるんですが

Posted: 2010年7月06日(火) 16:53
by ISLe
> kadai4 a.exe > a.csvとしてエクセルで開いたら
> 図のような文字化けを起こしました
> 文字コードが悪いのかな?

cygwin版gccでコンパイルしてますか?
コンパイルオプションに
-fexec-charset=cp932
を追加するとShiftJISで出力するようになりますけど。
#そのかわりbashで文字化けする。

Re:課題に取り組んでいるんですが

Posted: 2010年7月06日(火) 19:54
by 南瓜
う~ん、駄目でした…
プログラム自体は問いの趣旨通りなのかな?
それとも
>for 文の中で座標をコンマ区切りで出力します。
>printf("%d,%d\n", x, y);
がうまくできていないからか?

Re:課題に取り組んでいるんですが

Posted: 2010年7月08日(木) 12:21
by 南瓜
昨日投稿したと思ったのにしてなかったorz
問い2が出来たんですけど、もっと見やすく出来ないですかね?

Re:課題に取り組んでいるんですが

Posted: 2010年7月08日(木) 17:49
by mats
自分なら,
section[(int)(x*10)]++;
のように書きますかね.


気になった点をいくつか.
まず,nはintで宣言した方がいいかと思われます.

それと,xは配列にする意味はあるのでしょうか?
最後に値を表示しないのならば,1つの変数で良さそうですが…

最後に,既に議論されていたとは思うのですが,
0以上1未満の数しか発生しませんがよろしいのでしょうか?

Re:課題に取り組んでいるんですが

Posted: 2010年7月08日(木) 22:53
by 南瓜
>section[(int)(x*10)]++;
この形が話されていたキャストですね

確かにnはintの方がいいですね

0以上1未満の数の発生でいいみたいです

Re:課題に取り組んでいるんですが

Posted: 2010年7月08日(木) 23:14
by fatens
>>for 文の中で座標をコンマ区切りで出力します。
>>printf("%d,%d\n", x, y);
>がうまくできていないからか?

問2は解決できそうなので、遅くなりましたが問4を。
私はこのようなプログラムを想定しています。
必要な部分以外は書いていないので、不足しているところは自分で補ってください。
int main(void)
{
int i, n = 10;
int x = 0, y = 0;

for (i = 0; i < n; i++) {
switch (1~4の乱数を発生) {
case 1: x++; break; //東
case 2: x--; break; //西
case 3: y--; break; //南
case 4: y++; break; //北
}
printf("%d,%d\n", x, y);
}

return 0;
}
あとは、前に書いたように出力結果をcsvファイルにリダイレクトして、
エクセルなどでプロットすれば良いと思います。

Re:課題に取り組んでいるんですが

Posted: 2010年7月09日(金) 20:40
by 南瓜
コメント、プログラムを返信して下さった皆様
ありがとうございます。
無事、課題が終わりました。エクセルは1,-1みたいに
結果だけを表示させればグラフにすることが出来ました。

あと期限は、少しだけ延びたので大丈夫でした

Re:課題に取り組んでいるんですが

Posted: 2010年7月10日(土) 11:28
by 南瓜
解決を押すの忘れていた…