練習問題

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
もみのき

練習問題

#1

投稿記事 by もみのき » 8年前

はじめまして、C言語の質問です。
中学生です、以前プログラミングに詳しい先生から問題が出されたんです

次のようなコンソールプログラムを作成しなさい
1:要素数が10個のint型の配列を用意
2:0~99の乱数を作り配列の先頭から順番に配列の最後まで格納
ただ、既に配列に格納されているものと同じ値の数字は格納できない
3:10個の数字を配列に格納したら配列の先頭から順番に全て表示
4:配列に格納されている数字を昇順に並び替える
5:並び替えた後の配列の各要素を先頭から順番に全て表示

以上です
何ヶ月経ってもどうしても分からなくて悔しいんです
どなたかこの問題のソースプログラムを書き出してはいただけないでしょうか?
よろしくお願いいたします。

M

Re: 練習問題

#2

投稿記事 by M » 8年前

コード:

#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;
}
3)のところまでですが、一つのやり方として参考にしてみてください。
P.S. srandの初期化は工夫してください。

box
記事: 1746
登録日時: 9年前

Re: 練習問題

#3

投稿記事 by box » 8年前

M さんが書きました: 3)のところまでですが、一つのやり方として参考にしてみてください。
3点ほど気になる点があります。

1)iが0のとき、if文のところでNum[-1]を参照することとなり、まずいのではないでしょうか。
2)標準のCでは、bool, true, falseの定義がないように思います。
3)Num[]を外部変数にする必然性がないように思います。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

M

Re: 練習問題

#4

投稿記事 by M » 8年前

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 文の中に記述しているのも変数のスコープを意識してです。

アバター
へろりくしょん
記事: 92
登録日時: 9年前
住所: 福岡

Re: 練習問題

#5

投稿記事 by へろりくしょん » 8年前

気になる点と言えば、rand() % 100 で得た乱数が、既知のものであった場合、つまり重複した場合ですが。 無限ループに陥るような気がするのですが。
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;
}
ついでに昇順でソートもさせて見ました。

アバター
みけCAT
記事: 6277
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: 練習問題

#6

投稿記事 by みけCAT » 8年前

自分のやり方も載せておきます。
あらかじめ条件を満たす整数の一覧を作り、取得した整数を一覧から除いていきます。

コード:

#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で殴ればいい!(死亡フラグ)

box
記事: 1746
登録日時: 9年前

Re: 練習問題

#7

投稿記事 by box » 8年前

M さんが書きました: j >= 0 の条件で除外されるのでf、iが0の時はfor文の中身は実行されないです。
あぁ、そうですね。失礼いたしました。
M さんが書きました: C++の癖でそう書いてしまったので、Cでは int, 1, 0 で代用してください。
サンプルコードを載せる際は、質問者さんのところでコンパイルが通る(と思われる)ものの方がいいと思います。
質問者さんが混乱をきたさぬためにも。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

hss12

Re: 練習問題

#8

投稿記事 by hss12 » 8年前

重複チェック用配列を作ってみました。

コード:

#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;
}

閉鎖

“C言語何でも質問掲示板” へ戻る