C言語:配列を利用して横棒グラフを描いてみる

C言語初級

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億人

参考データ

世界人口ランキング・国別順位 2023年 UNFPA版

ソースコード

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言語:配列を利用して横棒グラフを描いてみるでした。

コメント

タイトルとURLをコピーしました