ページ 1 / 1
スケーリング
Posted: 2009年11月29日(日) 17:09
by 愛川
11個の非負の整数を入力として受け付ける。
これは,0点から10点までの人数だと考える。
このデータを利用して,*を使用したヒストグラムを出力したい。
人数が大きい場合には,*が画面を折り返してしまい,見にくくなってしまう。
そこで,次のようにスケーリング(縮小)を行いたい。
 *の数の最大を40 としたい。
 全データの最大値が,*の数を40個として表すことにする。
 例えば,最大値が80 だとして,それを40個とすることは50%に縮小することになる。
他のデータも同じように縮小する。
人数が20の場合は,*が10個になる。
また人数が25 の場合は,その半分が12.5なるが,小数点以下を四捨五入して*を13個とする。
 なお最大値が40以下の場合は,拡大も縮小も行わない。
出力形式は,最初の2桁が点数,一つ空白,続いて8桁が人数,一つ空白,*を0から40個となる。
下のようなプログラムは書けたのですが、スケーリングのやり方が分かりません。
よかったら教えていただけないでしょうか。
#include<stdio.h>
int main(void){
int i, j, data[11];
for(i = 0; i <= 10; i++){
scanf("%d", &data);
}
for(j = 0; j <= 10; j++){
printf("%2d %8d ", j, data[j]);
for(i = 0; i < data[j]; i++){
printf("*");
}
printf("\n");
}
return(0);
}
Re:スケーリング
Posted: 2009年11月29日(日) 17:28
by non
まず、環境を書いてください。
それに、添付するプログラムは、規約を読んで<pre>タグを使ってください。
さて、上のプログラムに、最大値を求めるプログラムを
追加してみてください。
Re:スケーリング
Posted: 2009年11月29日(日) 17:44
by 愛川
申し訳ありません。
OSはWindows、コンパイラはVisual C++です。
#include<stdio.h>
int main(void){
int i, j, data[11];
for(i = 0; i <= 10; i++){
scanf("%d", &data);
}
for(j = 0; j <= 10; j++){
printf("%2d %8d ", j, data[j]);
for(i = 0; i < data[j]; i++){
printf("*");
}
printf("\n");
}
return(0);
}
Re:スケーリング
Posted: 2009年11月29日(日) 20:38
by 愛川
最大値を求めるプログラムを追加しました。
ここからがどうしていいか全く分かりません。
よろしくお願いします。
#include<stdio.h>
int main(void){
int i, j, data[11], max = 0;
for(i = 0; i <= 10; i++){
scanf("%d", &data);
if(data > 0){
max =data;
}
}
for(j = 0; j <= 10; j++){
printf("%2d %8d ", j, data[j]);
for(i = 0; i < data[j]; i++){
printf("*");
}
printf("\n");
}
return(0);
}
Re:スケーリング
Posted: 2009年11月29日(日) 21:17
by ドラ
>最大値を求めるプログラムを追加しました。
本当に最大値が取得できているか確認しましたか?
>ここからがどうしていいか全く分かりません。
無事に最大値maxが算出できたなら、何個'*'を出力すればいいか計算するだけでしょう。
max <= 40 の場合は、data[j]個。
max > 40 の場合は基本的に40の(data[j]/max)倍の個数の'*'を表示すればいいですね。
ただし、小数点以下四捨五入の指示がありますので求めた個数に0.5を加算してから
小数点以下を切り捨てると良いでしょう。
Re:スケーリング
Posted: 2009年11月29日(日) 21:18
by non
最大値が求まっていません。
このままでは、最後に入力したデータがmaxになります。
Re:スケーリング
Posted: 2009年11月29日(日) 22:55
by 愛川
すみません、間違えていました。
最大値の部分は直せましたが、そのあとがうまくいきません。
#include<stdio.h>
int main(void){
int i, j, data[11], max = 0;
double a;
for(i = 0; i <= 10; i++){
scanf("%d", &data);
if(data > max){
max =data;
}
}
for(j = 0; j <= 10; j++){
printf("%2d %8d ", j, data[j]);
if(max <= 40){
for(i = 0; i < data[j]; i++){
printf("*");
}
}
else{
a = 40 / max + 0.5;
for(i = 0; i < a * data[j]; i++){
printf("*");
}
}
printf("\n");
}
return(0);
}
Re:スケーリング
Posted: 2009年11月29日(日) 23:56
by 星映
>a = 40 / max + 0.5;
maxが80のとき以下のようになってしまいます。
a = 40 / 80 + 0.5;
a = 0.5 + 0.5;
a = 1;
あとfor文内のa * date[j]の部分はループの内一回だけ 「a」*「maxの入った配列」 になりますので、
i < a * max
i < 1 * 80
i < 80
です。つまり、「maxの入った配列」のときは「*」が80個並びます。
今回間違っている部分は四捨五入する場所です。四捨五入するのは「*」の表示個数です。
頑張ってみてください。
Re:スケーリング
Posted: 2009年11月30日(月) 00:36
by 愛川
以下のようになったのですが…
出力が若干うまくいきません。
#include<stdio.h>
int main(void){
int i, j, data[11], max = 0;
double a;
for(i = 0; i <= 10; i++){
scanf("%d", &data);
if(data > max){
max =data;
}
}
for(j = 0; j <= 10; j++){
printf("%2d %8d ", j, data[j]);
if(max <= 40){
for(i = 0; i < data[j]; i++){
printf("*");
}
}
else{
a = 40 * data[j] / max;
for(i = 0; i < a + 0.5; i++){
printf("*");
}
}
printf("\n");
}
return(0);
}
Re:スケーリング
Posted: 2009年11月30日(月) 02:26
by 星映
>以下のようになったのですが…
>出力が若干うまくいきません。
>a = 40 * data[j] / max;
>for(i = 0; a + 0.5; i++){
> printf("*");
>}
おそらくscanfで0を入力すると0が入った配列は1になるでしょう。
なぜならi < a + 0.5が原因です。
scanfで0ならaは必然的に0になります。
i < 0 + 0.5 → i < 0.5になります。
i = 0のときは → 0 < 0.5(結果はTRUE)
そのため最低一回は 「*」を表示します。
自分なりに作ってみました。あと肝心の式の部分は(double)(~) int(a)などと書いていますが、
便利なので使わせて頂いてます。もし分からなければ質問していただいて結構ですよ。
#define OK1~OK3の部分や#ifndef,#ifdef,#endifは無駄なおまけです。
#include<stdio.h>
//#define OK1
//#define OK2
//#define OK3
int main(void)
{
int i, j, data[11], max = 0;
double a;
for(i = 0; i <= 10; i++)
{
#ifdef OK1
scanf("%d", &data);
#endif
#ifdef OK2
data = i * i;
#endif
#ifdef OK3
data = i * 100;
#endif
#ifndef OK1
#ifndef OK2
#ifndef OK3
printf("#defineのOK1かOK2かOK3のコメントをはずしてください\n");
printf("コメントをはずした後コンパイルしてください。\n");
return(0);
//コメントははずすだけで結構です。
#endif
#endif
#endif
if(data > max)
{
max = data;
}
}
printf("max %d\n",max);
for(j = 0; j <= 10; j++)
{
printf("%2d %8d ", j, data[j]);
if(max <= 40)
{
for(i = 0; i < data[j]; i++)
{
printf("*");
}
}
else
{
if( 40 > (a = (double)(data[j]) / (double(max) / 40) ) )
{
a += 0.5;
}
for(i = 0; i < int(a); i++)
{
printf("*");
}
}
printf(" %d ", i );
printf("\n");
}
return(0);
}
Re:スケーリング
Posted: 2009年11月30日(月) 09:04
by non
極力、本人のプログラムを活かすなら
for(i = 0; i <(int)( a + 0.5 ); i++){
Re:スケーリング
Posted: 2009年11月30日(月) 23:59
by 愛川
皆様、ありがとうございます。
以下のようなプログラムで合っているかと思うのですが…
無駄な処理など入っていますでしょうか?
#include<stdio.h>
int main(void){
int i, j, data[11], max;
double a;
scanf("%d", &data[0]);
max = data[0];
for(i = 1; i <= 10; i++){
scanf("%d", &data);
if(data > max){
max = data;
}
}
for(j = 0; j <= 10; j++){
printf("%2d %8d ", j, data[j]);
if(max <= 40){
for(i = 0; i < data[j]; i++){
printf("*");
}
}
else{
a = (int)(max / 40 + 0.5);
for(i = 0; i < (int)(data[j] / a + 0.5); i++){
printf("*");
}
}
printf("\n");
}
return(0);
}
Re:スケーリング
Posted: 2009年12月01日(火) 00:52
by 星映
回答します。(前回は無駄な回答ごめんなさい)
>scanf("%d", &data[0]);
>max = data[0];
>for(i = 1; i <= 10; i++){
> scanf("%d", &data);
> if(data > max){
> max = data;
> }
>}
scanf("%d, &data[0]);
max = data[0];
を分けている意図が分かりません。ここは消してfor文のiの開始を0にするべきです。
>a = (int)(max / 40 + 0.5);
aにスケーリングの比率を代入する際、int型でキャストしている部分が謎です。それと比率には四捨五入は必要ないです。(「*」の表示個数をint型でキャストしているのは問題ないですが。)
以上です。頑張ってください。
Re:スケーリング
Posted: 2009年12月01日(火) 08:43
by non
>scanf("%d, &data[0]);
>max = data[0];
>を分けている意図が分かりません。ここは消してfor文のiの開始を0にするべきです。
これは、maxに初期値を入れるためですね。今回は、点数入力に範囲があるので(0から10点)
max=0に初期化すればi=0からでOKです。
Re:スケーリング
Posted: 2009年12月01日(火) 08:56
by non
>点数入力に範囲があるので(0から10点)
上限はなかったですね。
無駄というほどではありませんが、このような解答もあるという例で
#include<stdio.h>
int main(void){
int i, j, data[11], max=0;
double a;
for(i = 0; i <= 10; i++){
scanf("%d", &data);
if(data > max){
max = data;
}
}
a=(max>40)? max/40.0:1.0;
for(j = 0; j <= 10; j++){
printf("%2d %8d ", j, data[j]);
for(i = 0; i < (int)(data[j] / a + 0.5); i++){
printf("*");
}
printf("\n");
}
return(0);
}
Re:スケーリング
Posted: 2009年12月02日(水) 00:55
by 愛川
回答してくださった皆様、ありがとうございます。
ようやく自分でも納得いくプログラムができました。
またなにかありましたらよろしくお願いいたします。