• ベストアンサー

先頭0で重複のない配列を作りたい

重複なく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; }

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

  • ベストアンサー
  • reset_cat
  • ベストアンサー率68% (94/138)
回答No.1

まず、このプログラムで本当に結果が出力できたんでしょうか? 気づいた点で・・・ >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); これも無限ループになりませんか?

rinnshan
質問者

お礼

回答ありがとうございました。 そうですね。上のループはcomp[0]=0だったら 無限ループになってしまいますね。 下は私の環境では無限ループにならないようなのですが、 iとjが逆であることに気付きました。

その他の回答 (3)

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.4

}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); のようにして下さい。

rinnshan
質問者

お礼

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

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.3

重複した項目を選択したくないのであれば 乱数によって選ぶもの自体の重複を避けたほうがいいでしょう ベースとなるデータを配列にとっておいてそこの何番目かを選択するようにしてみましょう 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]; といった具合にしてやればいいように思いますよ

rinnshan
質問者

お礼

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

  • Trick--o--
  • ベストアンサー率20% (413/2034)
回答No.2

重複以前に 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]を出力する かな。

rinnshan
質問者

お礼

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

関連するQ&A

  • 逆向きの数字を比較するぷろぐらむの一部

    コンピュータが任意に乱数で4ケタの数字を入力し、それを配列に 格納する。 そして、人間がその数字を逆向きに4ケタ、数字を配列に格納する。 というプログラムの一部を記載しました。 ところが、逆向きに入力してみてもうまく全て「間違いです。」 と表示されてしまいます。どこがおかしいか指摘していただきたいです。 よろしくお願いいたします。 do{ val=rand()%10; 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(j<i); comp[i]=val; } for(i=0;i<4;i++) { printf("%d",comp[i]); } fflush(stdout); sleep(500); printf("\r入力せよ:"); scanf("%s",human); for(i=0;i<4;i++) { if(human[i]!=comp[3-i]) { ero=1; break; } } if(ero==0) { printf("正解です。\n"); seikai++; } else { printf("\a間違いです。\n"); }

  • C言語でこのプログラムを完成させるには

    C言語でこのプログラムを完成させるには C言語初心者です。 1~6の乱数を100回発生させて、それぞれの出現回数をカウントし、ヒストグラムとして表示するプログラムを作成したいのですが上手くいきません。 #include <stdio.h> #include <time.h> #include <stdlib.h> int rnd(int m, int n) { return (int)(n-m+1)*(rand()/(RAND_MAX+0.1))+m; } int main(void) { int i, j, r; int hist[7]; for (i=1; i<7; i++) hist[i]=0; srand((unsigned)time(NULL)); for (i=0; i<100; i++) { r=6; while (6-- > 0) putchar('*'); putchar('\n'); } for (i=1; i<7; i++) { printf("%2d:", i); for (j=0; j<hist[i]; j++) printf("*"); printf("\n"); } return 0; } 何がいけないのでしょうか? よろしくお願いします。

  • 文字化けして表示される。

    本プログラムは、8色の色(白、黒、赤、青、黄、緑、橙、茶)から四文字を選択して重複なく表示させるプログラムです。 ところが、表示させるときに文字化けして「菌数」などと文字化けして表示されてしまいます。 これはなぜなのでしょうか? #include<stdio.h> #include<stdlib.h> #include<time.h> int main(void) { char *iro[8]={"白","黒","赤","青","黄","緑","橙","茶"}; int x,i,j; char atesase[4]; srand(time(NULL)); /*重複をなくすための処理*/ for(i=0;i<4;i++) { do{ x=rand()%8; for(j=0;j<i;j++) { if(atesase[j]==x) { break; } } }while(j<i); atesase[i]=x; } /*表示させるための処理*/ for(i=0;i<4;i++) { printf("%c",iro[atesase[i]][0]); } return 0; }

  • C++で乱数を重複しないように発生させる

    C++で乱数を重複しないように発生させるようにプログラムを変更しろと言われたのですが、できません。 教えていただきたいです。 #include<iostream> #include<cstdlib> #include<cstring> #include<ctime> using namespace std; int main() { int i,n; int *p; cout<<"何個記憶しますか?"<<endl; cin>>n; p=new int[n]; if(p==NULL){ cout<<"記憶域の確保に失敗しました。"<<endl; return 1; } srand((unsigned)time(NULL)); rand(); i=0; while(i<n){ p[i]=1+(int)((double)rand()/(RAND_MAX+1.0)*75); if(p[i]==p[i]) cout<<"p["<<i<<"]の値"<<p[i]<<endl; i++; } delete[] p; return 0; }

  • java

    このプログラムをjavaでかくとどうなりますか? #include<stdio.h> #include<stdlib.h> #include<time.h> int comp(const void *a, const void *b){  return *(int*)a - *(int*)b; } int main(void){  int i;  int sep[9];  srand((unsigned int)time(NULL));  sep[0] = 0;  sep[8] = 100;  for(i=1;i<8;i++){   sep[i] = rand() % 101;  }  qsort(sep+1, 7, sizeof(int), comp);  for(i=0;i<8;i++){   printf("a[%d] = %d;\n", i, sep[i+1] - sep[i]);  }  return 0; }

    • ベストアンサー
    • Java
  • クイックソート

    #include<stdio.h> #include<stdlib.h> #define MAX 10 int comp(const void *i,const void *j); int main(void) { int sort[MAX], i ; for(i=0 ; i<MAX ; i++){ sort[i] = rand(); } qsort(sort, MAX, sizeof(int), comp); for( i=0; i<MAX ; i++) printf("%d\n", sort[i]); return 0; } int comp (const void *i, const void *j) { return *(int*)i - *(int*)j; } これはクイックソートのプログラムなのですが、 int comp (const void *i, const void *j) { return *(int*)i - *(int*)j; } この部分がわかりません。ここでソートしているのですか?

  • C言語の配列の入れ方について質問です。

    下記のプログラムで1234という連続した数字を入れたら配列val[0]~[3]に val[0] = 1 val[1] = 2 val[2] = 3 val[3] = 4 というように入れたいのですが、どのようにして別々にすれば良いですか?宜しくお願いします。 #include<stdio.h> int main(void) { int num[10]; int val[4]; int i; printf("式:"); scanf("%d",num); for(i=0;i<4;i++){ val[i] = 0; } for(i=0; i<4; i++){ if((num[i] >= 1) && (num[i] <= 9)){ /*1から9の数値が入ったならば*/ val[i] = num[i]; } } for(i=0; i<4; i++){ printf("答え%d:%d\n",i,val[i]); } }

  • 4桁の英字の3桁目を当てるプログラム

    乱数でとってくる4ケタの英字の3桁目を入力して当てるプログラムを 組もうとしているのですが、コンパイラしてもいまいちうまくいきません。 特に下に書いたプログラムのこの部分が違っていると思い どのように修正したらよいのか指摘していただきたいです。 human=getchar(); if(comp[2]!=human) { ero=1; } よろしくお願いします。 #include<stdio.h> #include<stdlib.h> #include<time.h> #include<string.h> int sleep(unsigned long x) { clock_t c1=clock(),c2; do{ if((c2=clock())==(clock_t)-1) { return 0; } }while(1000.0*(c2-c1)/CLOCKS_PER_SEC<x); return 1; } int main(void) { int num,val,i,j; char comp[21]; char human; int ero=0; int try_count=0; int seikai=0; clock_t start,end; int num1; char eiji[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; srand(time(NULL)); puts("英字記憶トレーニング"); do{ printf("挑戦するレベル(3~20):"); scanf("%d",&num1); }while(num1<3 || num1>20); printf("%d個の英字を記録しましょう。\n",num1); start=clock(); do{ for(i=0;i<num1;i++) { comp[i]=eiji[rand()%strlen(eiji)]; } comp[num1]='\0'; printf("%s",comp); fflush(stdout); sleep(125*num1); printf("\r%*s\r3番目の英字を入力してください:",num1,""); human=getchar(); if(comp[2]!=human) { ero=1; } if(ero==0) { printf("正解です。\n"); seikai++; } else { printf("\a間違いです。\n"); } try_count++; }while(try_count<2); end=clock(); printf("%d回中%d回成功しました。\n",try_count,seikai); printf("%.1f秒でした。\n",(double)(end-start)/CLOCKS_PER_SEC); return 0; }

  • C言語について質問です。

    ソートについて勉強していて、乱数列の要素数Nの値を変えていきバブルソートの交換回数、比較回数を数えるプログラムを作り、後は処理時間について調べたいのですが、処理時間を出力するのはどうやってやるのですか?教えてください。以下に乱数を生成するrand.cとバブルソートを行うbubblesort.cを記載します。これに処理時間を出力するようにしてもらいたいのですが、どうしたらいいですか?解説とソースファイルをよろしくお願いします。 rand.c #include <stdio.h> #include <stdlib.h> #include <time.h> #define N 1000 int num[N]; int makeDataFile ( void ) { int i; FILE *fp; char s[100]; int num[N]; srand ( ( unsigned )time ( NULL ) ); fp = fopen ("rand1.txt", "w" ); if ( fp == NULL ) exit(1); for ( i = 0; i < N; i++ ){ fprintf ( fp, "%d\n", rand()%100 ); } fclose ( fp ); fp = fopen ( "rand1.txt", "r" ); if ( fp == NULL ) exit(1); while( fgets ( s, sizeof (s), fp ) ) { printf ( s ); } fclose ( fp ); return N; } bubblesort.c #include <stdio.h> #include <time.h> extern int makeDataFile ( void ); extern int num[]; void BubbleSort ( int x[] , int n ); void Show ( int x[] , int n ); int comp; int swap; void BubbleSort ( int x[] , int n ) { int i, j, tmp; for ( i = 0; i < n-1; i++ ) { for ( j = n-1; j > i; j-- ){ comp++; if ( x[i] > x[j] ){ swap++; tmp = x[j]; x[j] = x[i]; x[i]= tmp; Show ( x , n ); } } } } void Show ( int x[] , int n ) { while ( n-- ) printf ( "%d " , *x++ ); printf ( "\n" ); } int main(void) { int i, j, n , tmp; FILE *fp; comp = 0; swap = 0; n = makeDataFile(); fp = fopen ( "rand1.txt", "r" ); if ( fp == NULL ) return 1; for ( i = 0; i < n; i++ ){ fscanf ( fp, "%d", &(num[i] ) ); } fclose ( fp ); printf ( "\nbefore bubblesort\n" ); Show ( num , n ); printf ( "\n" ); printf ( "progress bubblesort\n" ); BubbleSort ( num , n ); printf ( "\n" ); printf ( "after bubblesort\n" ); Show ( num , n ); printf ( "\n" ); printf ( "count of comparisons : %d\n" , comp ); printf ( "count of swap : %d\n" , swap ); return 0; }

  • 配列

    /*10個の数字を受け取り,その中に一致する2つの数字があるかどうかを報告するプログラム*/ #include<stdio.h> int main(void) { int i,j,k; int item[9]; printf("10個の数字を入力してください\n"); for(i=0;i<10;i++) scanf("%d",&item[i]); for(j=0;j<10;j++) { for(k=j+1;k<10;k++) { if(item[j]==item[k]) printf("%dが2つ存在します.\n",item[j]); } } return 0; } というプログラムでエラーが出てしまいました. エラー内容は Stack around the variable 'item' was corrupted というものです. 原因を知りたいです.よろしくお願いします.

専門家に質問してみよう