三角形の描画


改行のタイミング」では「*」で長方形を描画するプログラムを作りましたが、今回は三角形を描画するプログラムを作ってみます。

三角形といっても、1行目は「*」1個、2行目は「*」2個…という具合に出力することで、最も簡単な直角三角形を描くことにします。

※イメージ

*

**

***

1.三角形の描画の基本


今までのような2重ループは、外側のループ(行)と内側のループ(列)の両方とも、繰り返し回数が明確に決まっていました。

しかし、今回の三角形を描画するためには、外側のループ(行)は繰り返し回数が明確ですが、内側のループ(列)の繰り返し回数は一定になりません。1行目は1回、2行目は2回…という具合に、外側のループが更新されるごとに、繰り返し回数が異なっています。

この実現には、内側のループで外側のループのカウンタ値を利用する必要があります。

 

下記は「入力値(自然数)を高さとする直角三角形(左下が直角)を『*』で描く」プログラムです。


直角三角形1(C)


#include <stdio.h>

int main(void){
    int i, j, h;
    printf("三角形の高さ:");
    scanf("%d", &h);

    for(i=1; i<=h; i++){
        for(j=1; j<=i; j++){
            printf("*");
        }
        printf("\n");
    }
    return 0;
}

直角三角形1(Java)

import java.util.Scanner;
public class Triangle1 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int h;
        System.out.print("三角形の高さ:");
        h = sc.nextInt();
        
        for(int i=1; i<=h; i++){
            for(int j=1; j<=i; j++){
                System.out.print("*");
            }
            System.out.println();
        }
    }    
}


実行結果(例)

三角形の高さ:4

*

**

***

****

 

外側のループでは、繰り返し回数が入力値 hと決まっています。

その一方で内側のループは、外側のループのカウンタ(= i)回ほど繰り返すようになっています。

こうすることで、行が増えるごとに「*」の出力回数も増やしているのです。

なお、繰り返し回数・条件が分かりやすいように、カウンタの初期値は1にしています。

2.三角形の描画と空白


次に、右下に直角がくる直角三角形を描いてみます。

今度は少し面倒で、「*」を右側にそろえて出力しなければなりません。

 

右側にそろえるという処理は、空白を複数回出力することで実現します。

問題は空白を何回出力するかですが、これは各行の「*」の個数と三角形の高さが関係しています。

「*」の個数と空白の個数の合計はどの行でも一定で、三角形の最大幅(最終行の「*」の個数)になっています。そしてこの最大幅は三角形の高さと同じなので、空白の個数 = 三角形の高さ - 「*」の個数となるのです。

 

下記は「入力値(自然数)を高さとする直角三角形(右下が直角)を『*』で描く」プログラムです。


直角三角形2-1(C)


#include <stdio.h>

int main(void){
    int i, j, h;
    printf("三角形の高さ:");
    scanf("%d", &h);

    for(i=1; i<=h; i++){
        for(j=1; j<=(h-i); j++){
            printf(" ");
        }
        for(j=1; j<=i; j++){
            printf("*");
        }
        printf("\n");
    }
    return 0;
}

直角三角形2-1(Java)

import java.util.Scanner;
public class Triangle2 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int h;
        System.out.print("三角形の高さ:");
        h = sc.nextInt();
        
        for(int i=1; i<=h; i++){
            for(int j=1; j<=(h-i); j++){
                System.out.print(" ");
            }
            for(int j=1; j<=i; j++){
                System.out.print("*");
            }
            System.out.println();
        }
    }    
}


実行結果(例)

三角形の高さ:4

 

 

   *

  **

 ***

****

 

Webページ表示の関係上、実行結果の三角形が変になっていますが、実際にはちゃんときれいな直角三角形ができあがります。

なお、上記の内側のループ2つは、1つのループにまとめることもできます。内側のループをどの行でも三角形の最大幅分繰り返し、カウンタ j の値が h - i 以下までは空白を、それより大きければ「*」を出力すると考えればよいのです。

 

下記は、「直角三角形2-1」の三角形の描画部分9行(9~17行目)を、内側のループ1つ版に置き換えたものです。実行結果は同じになります。


直角三角形2-2(C)

    for(i=1; i<=h; i++){
        for(j=1; j<=h; j++){
            if(j <= (h-i)){
                printf(" ");
            } else {
                printf("*");
            }
        }
        printf("\n");
    }

直角三角形2-2(Java)

        for(int i=1; i<=h; i++){
            for(int j=1; j<=h; j++){
                if(j <= (h-i)){
                    System.out.print(" ");
                } else {
                    System.out.print("*");
                }
            }
            System.out.println();
        }