はじめまして、C言語の質問です。
中学生です、以前プログラミングに詳しい先生から問題が出されたんです
次のようなコンソールプログラムを作成しなさい
1:要素数が10個のint型の配列を用意
2:0~99の乱数を作り配列の先頭から順番に配列の最後まで格納
ただ、既に配列に格納されているものと同じ値の数字は格納できない
3:10個の数字を配列に格納したら配列の先頭から順番に全て表示
4:配列に格納されている数字を昇順に並び替える
5:並び替えた後の配列の各要素を先頭から順番に全て表示
以上です
何ヶ月経ってもどうしても分からなくて悔しいんです
どなたかこの問題のソースプログラムを書き出してはいただけないでしょうか?
よろしくお願いいたします。
練習問題
Re: 練習問題
#include <stdio.h>
#define NUM_MAX 10
static int Num[NUM_MAX];
int main( int argc, char* argv[] ){
int i,j;
srand( 0 );
for ( i = 0; i < NUM_MAX; i++ ) {
bool flag = false;
do {
Num[i] = rand()%100;
for ( j = i-1; j >= 0; j-- ) {
if ( Num[i] == Num[j] ) {
flag = true;
break;
}
}
} while ( flag );
printf( "Num[%d] = %d\n", i, Num[i] );
}
return 0;
}
P.S. srandの初期化は工夫してください。
Re: 練習問題
1)iが0のとき、if文のところでNum[-1]を参照することとなり、まずいのではないでしょうか。
j >= 0 の条件で除外されるのでf、iが0の時はfor文の中身は実行されないです。
2)標準のCでは、bool, true, falseの定義がないように思います。
C++の癖でそう書いてしまったので、Cでは int, 1, 0 で代用してください。
3)Num[]を外部変数にする必然性がないように思います。
機能ではなく修辞的な意味合いです。このサンプルでは動作的には外部変数も局所変数でも変わりはないです。
"大文字始まりの変数名して外部変数とすることで意識的にその変数を目立たせる"という意図です。
他にNUM_MAXの定義の近くに置く、int i,j のそばに同じように並べない。とかです。
bool flag を for 文の中に記述しているのも変数のスコープを意識してです。
j >= 0 の条件で除外されるのでf、iが0の時はfor文の中身は実行されないです。
2)標準のCでは、bool, true, falseの定義がないように思います。
C++の癖でそう書いてしまったので、Cでは int, 1, 0 で代用してください。
3)Num[]を外部変数にする必然性がないように思います。
機能ではなく修辞的な意味合いです。このサンプルでは動作的には外部変数も局所変数でも変わりはないです。
"大文字始まりの変数名して外部変数とすることで意識的にその変数を目立たせる"という意図です。
他にNUM_MAXの定義の近くに置く、int i,j のそばに同じように並べない。とかです。
bool flag を for 文の中に記述しているのも変数のスコープを意識してです。
Re: 練習問題
気になる点と言えば、rand() % 100 で得た乱数が、既知のものであった場合、つまり重複した場合ですが。 無限ループに陥るような気がするのですが。
20行目で、flag = true; で、このフラグは下ろされませんので、 24行目のwhile ( flag ); は常に真ですね。
まぁ、参考までにと上げているものを重隅をつつくようで、ちょっとアレなのですが。
ここは、重複しているかチェックするより、素直にシャッフルした方が素直ではないかと。
ついでに昇順でソートもさせて見ました。
20行目で、flag = true; で、このフラグは下ろされませんので、 24行目のwhile ( flag ); は常に真ですね。
まぁ、参考までにと上げているものを重隅をつつくようで、ちょっとアレなのですが。
ここは、重複しているかチェックするより、素直にシャッフルした方が素直ではないかと。
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int sort(const void *p1, const void *p2)
{
return *(int*)p1 - *(int*)p2;
}
int main(void)
{
int i, num[100];
srand((unsigned)time(NULL));
for(i = 0; i < 100; i++) num[i] = i;
for(i = 0; i < 100; i++){
int sp = rand() % 100;
num[i] ^= num[sp] ^= num[i] ^= num[sp];
}
for(i = 0; i < 10; i++) printf("%d\n", num[i]);
qsort(num, 10, sizeof(int), sort);
for(i = 0; i < 10; i++) printf("%d\n", num[i]);
return 0;
}
Re: 練習問題
自分のやり方も載せておきます。
あらかじめ条件を満たす整数の一覧を作り、取得した整数を一覧から除いていきます。
あらかじめ条件を満たす整数の一覧を作り、取得した整数を一覧から除いていきます。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int result[10];
int temp[100];
int index,i,j;
int tempint;
/*乱数の初期化*/
srand((unsigned int)time(NULL));
/*整数一覧の初期化*/
for(i=0;i<100;i++)temp[i]=i;
/*10個の整数を取得*/
for(i=0;i<10;i++) {
/*どの整数を取得するか決める*/
index=rand()%(100-i);
/*指定された整数を代入*/
result[i]=temp[index];
/*指定された整数を一覧から除く*/
for(j=index;j<99;j++)temp[j]=temp[j+1];
}
/*10個の整数を表示*/
puts("取得した10個の整数");
for(i=0;i<10;i++)printf("%d\n",result[i]);
/*整数を昇順にソート*/
for(i=0;i<10;i++) {
for(j=0;j<9;j++) {
if(result[j]>result[j+1]) {
tempint=result[j];
result[j]=result[j+1];
result[j+1]=tempint;
}
}
}
/*10個の整数を表示*/
puts("昇順に並び替えた10個の整数");
for(i=0;i<10;i++)printf("%d\n",result[i]);
/*正常終了*/
return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: 練習問題
重複チェック用配列を作ってみました。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void){
int a[10]; /*1:要素数が10個のint型の配列*/
int b[100]={0}; /*重複チェック用配列 すべて0*/
int i, j;
int temp;
/*乱数の初期化*/
srand((unsigned)time(NULL));
/*2:0~99の乱数を作り配列の先頭から順番に配列の最後まで格納*/
for(i=0; i<10; i++){
do{
a[i]=rand()%100;
}while(b[a[i]]); /*重複していた場合はやり直し*/
b[a[i]]=1; /*既に配列に格納されているものと同じ値の数字をチェック*/
}
/*3:10個の数字を配列に格納したら配列の先頭から順番に全て表示*/
puts("10個の数字が格納された配列を先頭から順番に全て表示");
for(i=0; i<10; i++){
printf("%d\n", a[i]);
}
/*4:配列に格納されている数字を昇順に並び替える*/
for(i=0; i<10-1; i++){
for(j=i+1; j<10; j++){
if(a[i]>a[j]){
temp=a[j];
a[j]=a[i];
a[i]=temp;
}
}
}
/*5:並び替えた後の配列の各要素を先頭から順番に全て表示*/
puts("昇順に並び替えた後の配列を先頭から順番に全て表示");
for(i=0; i<10; i++){
printf("%d\n", a[i]);
}
return 0;
}