重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

重複なく4つの領域を持つ配列に数字を代入したい(先頭は0以外の
数字)と思って書いたプログラムです。

しかし、コンパイルしてみると重複が発生してしまいます。
これはなぜ発生してしまうのでしょうか?
よろしくお願いします。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int main(void)
{

int num,val,i,j;
int comp[4];

srand(time(NULL));
puts("4桁の数字を記憶して逆向きに入力しましょう。");

val=rand()%10;
do{
comp[0]=val;
}while(comp[0]==0);

for(i=1;i<4;i++)
{
do{
val=rand()%10;
for(j=0;j<i;j++)
{
if(comp[j]==val)
{
break;
}
}
}while(i<j);
comp[i]=val;
}

for(i=0;i<4;i++)
{
printf("%d",comp[i]);
}

return 0;
}

A 回答 (4件)

まず、このプログラムで本当に結果が出力できたんでしょうか?


気づいた点で・・・

>val=rand()%10;
>do{
>comp[0]=val;
>}while(comp[0]==0);

これってvalが0だったら無限ループになりませんか?
あと、

>do{
>val=rand()%10;
>for(j=0;j<i;j++)
>{
>if(comp[j]==val)
>{
>break;
>}
>}
>}while(i<j);

これも無限ループになりませんか?
    • good
    • 0
この回答へのお礼

回答ありがとうございました。
そうですね。上のループはcomp[0]=0だったら
無限ループになってしまいますね。

下は私の環境では無限ループにならないようなのですが、
iとjが逆であることに気付きました。

お礼日時:2009/11/30 16:27

}while(i<j);


comp[i]=val;
}
上記の}while(i<j);を
}while(j<i);に変えて下さい。(iとjを入れ替える)

あと、#2のかたが言っているように
val=rand()%10;
do{
comp[0]=val;
}while(comp[0]==0);
の部分を
do{
val=rand()%10;//ここに移動
comp[0]=val;
}while(comp[0]==0);
のようにして下さい。
    • good
    • 0
この回答へのお礼

回答ありがとうございました。
私も下の方の指摘のように、変更したら
あなた様と同じ変更になりました。

お礼日時:2009/11/30 16:31

重複した項目を選択したくないのであれば 乱数によって選ぶもの自体の重複を避けたほうがいいでしょう



ベースとなるデータを配列にとっておいてそこの何番目かを選択するようにしてみましょう

int nBase[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
としておいて
第一項の選択は
int val = rand() % 9;
comp[0] = nBase[ val ];
として 決定します
第二項目は 第一項で使った部分を細工します
// 使用済みのベースデータを排除
nBase[val] = nBase[9];
nBase[9] = 0;
val = rand() % 9;
comp[1] = nBase[ val ];

第三項も同様に
nBase[val] = nBase[8];
nBase[8] = 0;
val = rand() % 8;
comp[2] = nBase[val];

第四項も同様に
nBase[val] = nBase[7];
nBase[7] = 0;
val = rand() % 7;
comp[3] = nBase[val];
といった具合にしてやればいいように思いますよ
    • good
    • 0
この回答へのお礼

なるほど。そんな方法があるんですね。
参考にしたいと思います。

お礼日時:2009/11/30 16:30

重複以前に


val=rand()%10;
do{
comp[0]=val;
}while(comp[0]==0);

val=0のとき、無限ループする。
rand()をdoループの中に。
do{
val=rand()%10;
comp[0]=val;
}while(comp[0]==0);


フロー
A・comp[0]に1~9の値を入れる
B・i = 0
C・0~9の値を決める
D・comp[0]~comp[i]にその値があれば、Bに戻る
E・その値をcomp[i+1]に入れる
F・i++
G・i<4ならCに戻る
H・comp[0]~comp[3]を出力する

かな。
「先頭0で重複のない配列を作りたい」の回答画像2
    • good
    • 0
この回答へのお礼

フローを書いていただきありがとうございました。
参考にしたいと思います。

お礼日時:2009/11/30 16:28

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!