テストの点数から順位を求める問題

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
kopi
記事: 19
登録日時: 11年前

テストの点数から順位を求める問題

#1

投稿記事 by kopi » 11年前

こんにちは。
この前C言語を始めたのですが、教えてほしいことがあります。

テストの点数のデータがあったとき、for文の2重ループを使った比較法では、n^2回比較が行われてしまいます。
そこで、その繰り返し回数を減らしたアルゴリズムの問題が教科書に載っていたのですが、そこでわからない点があります。

考え方は教科書の文章をそのまま転載します。

****転載*****
点数の範囲を0~100としたとき、その点数の範囲を添え字にする。
rank[0]~rank[100]の配列ともう一つ余分なrank[101]という配列を用意し内容を0クリアしておく。
まず各得点ごとに対応する添え字の配列の内容を+1する。
次に101の要素に初期値の1(順位を示す)を入れておき、rank[100]→rank[0]の各配列に対し、1つ右の要素の内容を加えていく。
これで<得点+1>の添え字の配列の順位が求められる。例えば100点の順位は101の位置に、88点の順位は89の位置にといった具合である。
****終了*****

コード:

#include<stdio.h>

#define MAX 101

int main(void)
{
	int a[] = {56, 25, 55, 61, 67, 76, 88, 100, 99, 86, 52};
	int i, len, rank[MAX]={0};

	printf("Before : %d %d\n", a[0], a[2]);	  // 確認用(before)
	len = sizeof(a)/sizeof(a[0]);
	rank[MAX] = 1;

	for(i=0;i<len;i++){
		rank[a[i]] = 1;
	}
	
	for(i=MAX-1;i>=0;i--){
		rank[i] = rank[i] + rank[i+1];
	}
	
	printf("After : %d %d\n", a[0], a[2]);	// 確認用(After)
	printf("\n得点 \t 順位\n");
	printf("------------\n");
	for(i=len-1;i>=0;i--){
		printf("%d \t %d\n", a[i], rank[a[i]+1]);
	}
	return 0;
}
一応、自分なりに書いたコードが上のコードなのですが、実行してみると、a[0]の配列が1になってしまいます。
コメントアウトしてある部分で、Beforeの部分ではちゃんと56と出るのですが、Afterの部分では1になってしまいます。
BeforeとAfterの間で書き換えられているとは思うのですが、
a[0]に数値を代入したような文が今の私には見えないので、どこでa[0]が書き換えられているのかご教授お願いします。

OS : Windows 7
コンパイラ : Borland C++ Compiler 5.5

初級者
記事: 200
登録日時: 14年前

Re: テストの点数から順位を求める問題

#2

投稿記事 by 初級者 » 11年前

rank[MAX] = 1;
の行が怪しいです。
配列の定義範囲外の領域を
破壊しています。

kopi
記事: 19
登録日時: 11年前

Re: テストの点数から順位を求める問題

#3

投稿記事 by kopi » 11年前

初級者 さんが書きました:rank[MAX] = 1;
の行が怪しいです。
配列の定義範囲外の領域を
破壊しています。
なるほど、確かにそうですね。気づきませんでした。

101個目の配列に1を格納しなければならないので、MAXを102とし、二つ目のfor文を配列100番目からループするようにしたところ
無事表示できました。

コード:

#include<stdio.h>

#define MAX 102

int main(void)
{
	int a[] = {56, 25, 55, 61, 67, 76, 88, 100, 99, 86, 52};
	int i, len, rank[MAX]={0};

	printf("%d %d\n", a[0], a[2]);	// 確認用(before)
	len = sizeof(a)/sizeof(a[0]);
	rank[MAX-1] = 1;

	for(i=0;i<len;i++){
		rank[a[i]] = 1;
	}
	
	for(i=MAX-2;i>=0;i--){
		rank[i] = rank[i] + rank[i+1];
	}
	
	printf("%d %d\n", a[0], a[2]);	// 確認用(After)
	printf("\n得点 \t 順位\n");
	printf("------------\n");
	for(i=len-1;i>=0;i--){
		printf("%d \t %d\n", a[i], rank[a[i]+1]);
	}
	return 0;
}
ありがとうございました。

閉鎖

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