1次元配列を利用して、横棒グラフを描いてみます。
C言語の配列の1つの利用例として活用してください。
とりあえず横棒グラフを描く
例えば次のような配列の数値を使って
int points[5] = {2, 5, 7, 10, 4};
配列の数値の同じ数の■(←しかくと入力して変換できる全角文字です)を横に表示する横棒グラフを表示してみます。
実行イメージ
ソースコード
hairetu_graph1.c
/* hairetu_graph1.c 配列要素を使って横棒グラフを描いてみる */
#include <stdio.h>
int main(void){
int points[5] = {2, 5, 7, 10, 4};
int i, j;
/* 配列要素分繰り返す */
for(i=0; i<5; i++){
/* 横棒グラフを表示 */
for(j=0; j<points[i]; j++){
printf("■");
}
printf("\n");
}
return 0;
}
考え方
まず配列要素を取り出すことが大事です。
通常は、配列要素を順番に取り出すには、ループ処理を使ってこんな風に記述すると思います。
#include <stdio.h>
int main(void){
int points[5] = {2, 5, 7, 10, 4};
int i;
/* 配列要素分繰り返す */
for(i=0; i<5; i++){
printf("%d\n", points[i]);
}
return 0;
}
実行結果
2 5 7 10 4
上記で表示された数分の■を表示すれば横棒グラフっぽく見えるはずです。
要するに2なら2回、5なら5回、
printf("■");
実行すれば横棒グラフのように表示できます。
for文で取り出した 配列points[i] を利用してさらに内側にもう一つfor文を作れば、繰り返し条件にpoints[i]の値を使うことができます。
/* 配列要素分繰り返す */ for(i=0; i<5; i++){ /* 横棒グラフを表示 */ for(j=0; j<points[i]; j++){ printf("■"); } printf("\n"); }
忘れていけないのが、内側のfor文が終わった後の
printf("\n");
の処理です。
1つの横棒グラフを表示した後、改行しないと横にどんどん■が表示されるだけになってしまいます。
改行を省いた場合のイメージ
■■■■■■■■■■■■■■■■■■■■■■■■■■■■
世界の人口ベスト5を横棒グラフで表示する
2023年の世界人口データを使って、次のような横棒グラフを表示させてみます。
実行イメージ
世界の人口ベスト5(2022年) インド|■■■■■■■■■■■■■■ 14億人 中国|■■■■■■■■■■■■■■ 14億人 アメリカ|■■■ 3億人 インドネシア|■■ 2億人 パキスタン|■■ 2億人
参考データ
ソースコード
hairetu_graph2.c
#include <stdio.h>
int main(void){
int i, j;
char country[5][64] = {"インド", "中国", "アメリカ", "インドネシア", "パキスタン"};
int population[] = {14, 14, 3, 2, 2};
printf("世界の人口ベスト5(2023年)\n");
/* グラフを表示 */
for(i=0; i<5; i++){
printf("%20s|", country[i]); /* 国名 */
for(j=0; j<population[i]; j++){
printf("■");
}
printf(" %d億人\n", population[i]); /* 人口を表示 */
}
}
考え方
国名と人口データをそれぞれ別の1次元配列で格納しています。
配列の添え字で国名と人口数とが対応するようにしておくとグラフ表示が楽です。
例)添え字0(country[0]とpopulation[0])は、インドのデータを表す
char country[5][64] = {"インド", "中国", "アメリカ", "インドネシア", "パキスタン"}; int population[] = {14, 14, 3, 2, 2};
グラフの表示は、人口を表す配列populationを利用して、内側のfor文で数値分の■を表示しています。
for(j=0; j<population[i]; j++){ printf("■"); }
グラフ表示が終了後、グラフの先に○○億人という表示もしてみました。
printf(" %d億人\n", population[i]); /* 人口を表示 */
当初、国名をそのまま表示したのですが、グラフがずれて見にくいものになりました。
実行イメージ(非常にみにくい!)
世界の人口ベスト5(2023年) インド|■■■■■■■■■■■■■■ 14億人 中国|■■■■■■■■■■■■■■ 14億人 アメリカ|■■■ 3億人 インドネシア|■■ 2億人 パキスタン|■■ 2億人
国名を一定の文字数で揃えて右揃えで表示するためにprintf関数のフォーマット機能を使って%20sとしています。(%20sとすると半角20文字で表示し右揃えとなります)
printf("%20s|", country[i]); /* 国名 */
値が大きいデータのグラフ表示する
たとえば次のような市町村の人口をグラフ化してみます。
市町村 | 人口(人) |
---|---|
水戸市 | 270685 |
日立市 | 174508 |
ひたちなか市 | 156581 |
城里町 | 18097 |
東海村 | 37891 |
実行イメージ
水戸市|******************************************************270685人 日立市|**********************************174508人 ひたちなか市|*******************************156581人 城里町|***18097人 東海村|*******37891人
ソースコード
hairetu_graph3.c
#include <stdio.h>
int main(void){
int i, j, graph;
char city[5][64] = {"水戸市", "日立市", "ひたちなか市", "城里町", "東海村"};
int population[] = {270685, 174508, 156581, 18097, 37891};
/* 文字グラフを表示 */
for(i=0; i<5; i++){
printf("%20s|", city[i]); /* 市町村 */
graph = population[i] / 5000; /* グラフ表示用に少なくする */
for(j=0; j<graph; j++){
printf("*");
}
printf("%d人\n", population[i]); /* 実際の人口を表示 */
}
}
考え方
これまで紹介したグラフのデータは数値が小さかったため、データ数をそのまま同数の文字に置き換えることができましたが、今回は最大の値が27万(水戸市)となっています。
グラフとして表示できる文字数にするためグラフ表示用に人口を表すpopulationを全て5000で割ってグラフ表示用の条件に利用しています。
: graph = population[i] / 5000; /* グラフ表示用に少なくする */ for(j=0; j<graph; j++){ printf("*"); } : :
地球温暖化がすすんでいるか確認するグラフ
最後に身近な問題をグラフ化して本記事を終わりましょう。
地球温暖化がすすんでいるといわれています。
本当に地球温暖化はすすんでいるのかを具体的なデータを利用してC言語で表現してみます。
次の配列は2022年と1970年(約50年前)の水戸市の月別年間平均気温データです。
double temp1970[] = {1.7, 3.3, 3.3, 10.7, 17.2, 19.1, 23.6, 25.0, 21.7, 15.3, 9.7, 3.5}; double temp2022[] = {2.8, 3.4, 8.3, 13.9, 17.5, 21.8, 26.1, 26.3, 23.2, 16.0, 12.7, 5.5};
元データは以下リンク先です。
これらは気象庁の各種データ・資料からお住いの地域ごとに検索参照できます。
この配列データを比較グラフにして表示してみます。
実行イメージ
水戸市の年間平均気温(月別) □ 1970年 ■ 2022年 1月|□ 1.7C 1月|■■ 2.8C(+1.1C) 2月|□□□ 3.3C 2月|■■■ 3.4C(+0.1C) 3月|□□□ 3.3C 3月|■■■■■■■■ 8.3C(+5.0C) 4月|□□□□□□□□□□ 10.7C 4月|■■■■■■■■■■■■■ 13.9C(+3.2C) 5月|□□□□□□□□□□□□□□□□□ 17.2C 5月|■■■■■■■■■■■■■■■■■ 17.5C(+0.3C) 6月|□□□□□□□□□□□□□□□□□□□ 19.1C 6月|■■■■■■■■■■■■■■■■■■■■■ 21.8C(+2.7C) 7月|□□□□□□□□□□□□□□□□□□□□□□□ 23.6C 7月|■■■■■■■■■■■■■■■■■■■■■■■■■■ 26.1C(+2.5C) 8月|□□□□□□□□□□□□□□□□□□□□□□□□□ 25.0C 8月|■■■■■■■■■■■■■■■■■■■■■■■■■■ 26.3C(+1.3C) 9月|□□□□□□□□□□□□□□□□□□□□□ 21.7C 9月|■■■■■■■■■■■■■■■■■■■■■■■ 23.2C(+1.5C) 10月|□□□□□□□□□□□□□□□ 15.3C 10月|■■■■■■■■■■■■■■■■ 16.0C(+0.7C) 11月|□□□□□□□□□ 9.7C 11月|■■■■■■■■■■■■ 12.7C(+3.0C) 12月|□□□ 3.5C 12月|■■■■■ 5.5C(+2.0C)
50年前(1970年)と比べて、どの月も平均気温が上がっていることが見て取れます。
3月などは、5℃も平均気温が上がっています。冬の時期の11月も3℃上がっているのは驚きです。
確かに温暖化は進んでいます。
ソースコード
temp_mito.c
/*
水戸市の1970年と2022年の年間平均気温の比較(月別)
*/
#include <stdio.h>
int main(void){
int i, j, graph_length;
double temp1970[] = {1.7, 3.3, 3.3, 10.7, 17.2, 19.1, 23.6, 25.0, 21.7, 15.3, 9.7, 3.5};
double temp2022[] = {2.8, 3.4, 8.3, 13.9, 17.5, 21.8, 26.1, 26.3, 23.2, 16.0, 12.7, 5.5};
printf("\n水戸市の年間平均気温(月別) □ 1970年 ■ 2022年\n\n");
for(i=0; i<12; i++){
/* 1970年 */
printf("%2d月|", i+1);
graph_length = (int)temp1970[i];
for(j=0; j<graph_length; j++){
printf("□");
}
printf(" %.1fC\n", temp1970[i]);
/* 2022年 */
printf("%2d月|", i+1);
graph_length = (int)temp2022[i];
for(j=0; j<graph_length; j++){
printf("■");
}
/* 1970年と+-で何度違うかも表示 */
printf(" %.1fC(%+.1fC)\n\n", temp2022[i], temp2022[i]-temp1970[i]);
}
return 0;
}
考え方
グラフ化するデータが小数点を含む気温のため、文字のグラフにするには少々無理があります。
そこで今回はあくまで比較できればという意味でグラフにするため、double型データをint型にキャスト(型変換)することで大雑把な数値にしています。
graph_length = (int)temp1970[i];
double型をint型にキャストすると、例えば実際のデータが5.5℃なら、5となります。
これをグラフで表示する際は
■■■■■ 5.5C
と表示しています。
実際に1970年と2022年で何℃位差があるのか?を表示するため2022年のグラフ表示の最後に以下のprintf文を使いました。
/* 1970年と+-で何度違うかも表示 */ printf(" %.1fC(%+.1fC)\n\n", temp2022[i], temp2022[i]-temp1970[i]);
比較として+1.0などと正負の符号をつけて表示したかったので、%+.1fとしています。
%のあとに+をつけることで1.0なども+1.0と表示してくれます。(ちなみに.1fは小数点以下1桁まで表示という意味になります)
以上、C言語:配列を利用して横棒グラフを描いてみるでした。
コメント