質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

2回答

2186閲覧

1から10までの数値を10000個生成し、各数値の出現頻度の算出

Sade_ni

総合スコア7

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

1クリップ

投稿2020/10/22 18:31

前提・実現したいこと

・引数で指定される2つの整数値の間の乱数を戻り値として返す
・グローバル変数は用いない
↑の関数を用いて1から10までの数値(またはキーボードから取り込む2つの数値)を10000個生成し、各数値の出現頻度を算出し、画面に出力させる

発生している問題

引数で指定される2つの整数値の間の乱数を戻り値として返す方法と数値の出現頻度の算出がわかりません

該当のソースコード

#include <stdio.h> #include <stdlib.h> #include <time.h> int random_range(int s, int e); int main(void) { int i, r, stat[11]={}; srand(time(NULL)); for(i = 0;i<10000;i++) { stat[i]=rand()%10+1; } for(i=0;i<10;++i) { printf("%d の出現回数%4d\n",i, stat[i]); } return 0; } int random_range(int s, int e) { int r; return r; }

試したこと

引数、戻り値を使用せずに10000個の1~10の数の生成を行いました。各数値の出現頻度の算出は試したもの実行できませんでした。

補足情報(FW/ツールのバージョンなど)

#include <stdio.h> #include <stdlib.h> #include <time.h> int random_range(int s, int e); int main(void) { int i, r, stat[11]={}; srand(time(NULL)); for() { r = random_range(1, 10); } return 0; } int random_range(int s, int e) { return r; }

テンプレートとしてこのソースコードが与えられていました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

とりあえず、提示されているソースで気が付いた点です。
1.stat[i]=rand()%10+1;ですが
iは0から9999まで変化します。
statは11個の配列なのでstat[10]が上限です。それ以上のiが出現すると暴走状態になります。
statは1~10の値を添え字にする前提です。
rへ1から10の数値を設定し、
stat[r]へ1加算するようにしてください。

2. for(i=0;i<10;++i) ですが
これだとiは0から9まで変化します。
たぶん、あなたが期待しているのは1から10思いますが、そのようにはなりません。
(++1をしてもiは1から10にはなりません)
for(i=1;i<11;i++)
としてください。
余談ですが、i++を使うケースは多々ありますが、++iを使うケースはそれほど多くありません。
i++をまず、確実に使えるようにしておけば十分です。

上記の修正で、とりあえず、それなりの結果がでるかと思います。

追記分です。
1.int random_range(int s, int e)
は、下限:s 上限:eが指定されたとき、s~eの範囲のランダムな数値を返す関数です。
10000回のループは、ここですべきではありません。
2.int random_rangeの呼び出し側は、

C

1for(i=0;i<10000;++i){ 2 r = random_range(1,10); 3 ++stat[r]; 4} 5for(i=1;i<11;i++) 6 printf("%d の出現回数%5d\n",i, stat[i]); 7} 8

とすべきです。
尚、random_rangeが本当に期待した結果を返すかどうか
チェックするするために
r = random_range(1,10);
の次の行へ
if (r < 1 || r > 11){
if (r < 1 || r > 10){
printf("error=d\n",r);
return 0;
}
を入れておくと、確認が可能になります。

投稿2020/10/23 01:46

編集2020/10/23 06:08
tatsu99

総合スコア5467

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Sade_ni

2020/10/23 03:32

教えて貰った所の修正と自分なりの調整を加えたら成功しました。教えていただきありがとうございます。
tatsu99

2020/10/23 03:44

「引数で指定される2つの整数値の間の乱数を戻り値として返す方法」は解決しましたか。 int random_range(int s, int e)の中身の部分です。 まだで、あれば、そちらも回答します。 まずは、外堀を埋めるのが先決なので、random_rangeの中身については、この回答では、触れませんでした。
Sade_ni

2020/10/23 04:04

#include <stdio.h> #include <stdlib.h> #include <time.h> int random_range(int s, int e); int main(void) { int i, r, stat[11]={}; srand(time(NULL)); random_range(1, 10); return 0; } int random_range(int s, int e) { int i, r, stat[11]={}; for(i=0;i<10000;++i) { r = rand()%e+s; ++stat[r]; } for(i=1;i<11;i++) printf("%d の出現回数%5d\n",i, stat[i]); } このような形にしたのですがどうでしょうか
tatsu99

2020/10/23 04:24

回答のほうに追記しました。
Sade_ni

2020/10/23 04:53

追記確認しました。私も当初その方法で行うつもりだったのですがコンパイルするとSegmentation fault (コアダンプ)と出ます。
tatsu99

2020/10/23 05:10

修正したソースを提示してください。
Sade_ni

2020/10/23 05:49

#include <stdio.h> #include <stdlib.h> #include <time.h> int random_range(int s, int e); int main(void) { int i, r, stat[11]={}; srand(time(NULL)); for(i=0;i<10000;++i) { r = random_range(1,10); ++stat[r]; } for(i=1;i<11;i++) printf("%d の出現回数%5d\n",i, stat[i]); return 0; } int random_range(int s, int e) { int r; rand()%e+s; return r; } こちらです
tatsu99

2020/10/23 05:57

int random_rangeですが rand()%e+s; では、rになにも設定されません。 そうするとrには、何が入っているのかわかりませんので、とんでもない値が入っていることもあり得ます。そうすると、呼び出し側に、とんでもない値が返ります。 r = rand()%e+s; とりあえず、上のようにしてください。そうすればrにあなたが設定しようとした値が入ります。
tatsu99

2020/10/23 05:59

上記の修正を行う前に、呼び出し側で r = random_range(1,10); の次の行へ if (r < 1 || r > 11){ printf("error=d\n",r); return 0; } をいれておくと、とんでもない値が返っていることがわかります。
tatsu99

2020/10/23 06:06

if (r < 1 || r > 11){でなく if (r < 1 || r > 10){ ですね。 失礼しました。(本文も訂正しておきます。)
Sade_ni

2020/10/23 16:50

返信遅れてすみません。言われた所修正したらできていました。本当に最後までありがとうございます。最後に質問なのですが if (r < 1 || r > 10){ printf("error=d\n",r); return 0; } はミスが生じた時のみ文字が出るものなのですか?また、他のソースコードにも応用できるのでしょうか
tatsu99

2020/10/23 22:35

はい。ミスが生じた時のみ文字が出ます。rが1~10の範囲以外ならエラー表示しています。 そのままでは、使えませんが、「ある値(x)の正常範囲が決まってるなら、xが正常範囲以外の時に、表示する」という原則を守れば使えます。
tatsu99

2020/10/23 22:46 編集

問題をよく読むと1~10の範囲の数値の生成だけでなく、例えば6~9の範囲の数値を10000万回生成することもできるようなint random_range(int s, int e)を作れというように見えます。 main側で r = random_range(1,10);を r = random_range(6,9); にした時、 rは正しく6~9の数値になっていますか? 正しいなら、6~9の各数値の出現回数は2500回前後の値になるはずです。
Sade_ni

2020/10/24 08:24

今回は、1~10の範囲での生成とそれの頻度を表せば良いのですが、 r = random_range(6,9);にし、 if (r < 6 || r > 9 ){ printf("error=d\n",r); return 0; } にして、実行してみましたがうまくいきませんでした。
tatsu99

2020/10/24 08:31

うまくいかなかったとは、rの値が6~9の範囲外になる場合があった、ということでしょうか? もし、そうであれば、random_rangeのコードに誤りがあります。 int random_range(int s, int e)の内容は、どのようになっていますか?
guest

0

まず、結果として欲しいものが「各数値の出現頻度」な訳ですから、結果は単体のintなどという形にはならず、数値の個数分の実数値にならないとおかしいです。
まずはそれをどう返すか?といったところから、考えてみると良いかと思います。

読み違いでした。

投稿2020/10/22 22:40

編集2020/10/23 02:54
amiya

総合スコア1218

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tatsu99

2020/10/23 01:01

「各数値の出現頻度」を画面に表示するのが目的なので、 「各数値の出現頻度」を返す関数を作るのが目的ではないと思いますが、いかがでしょうか。 また、各数値の出現頻度の定義なのですが 1が10000回のうち5000回出現したとすると 出現頻度は、0.5で良いのでしょうか。 この場合の出現頻度の意味が出現回数(5000)なのか、出現率(0.5)なのか出現率の百分率(50)なのか よくわかりませんでした。
amiya

2020/10/23 02:02

ああそうか。 『引数で指定される2つの整数値の間の乱数を戻り値として返す』 の方が関数の仕様ですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問