質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.49%

  • C

    3805questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • アルゴリズム

    420questions

    アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

for文でピラミッドの解説をお願いしたいです・・・

解決済

回答 5

投稿

  • 評価
  • クリップ 0
  • VIEW 7,811
退会済みユーザー

退会済みユーザー

#include <stdio.h>
int main(){
    int i, j, h;
    printf("何段? : ");
    scanf("%d", &h);

    for (i = 1; i <= h; i++) {
/* 1 */ for (j = 1; j <= h-i+1; j++) {      /* なぜ、h-i+1 なのか? なぜ、h-i じゃないのか? */
            putchar(' ');
        }
/* 2 */  for (j = 1; j <= (i-1)*2+1; j++) {      /* 理解不能(>皿<) */
            putchar('*');
        }
        putchar('\n');
    }


    return 0;
}

1 と 2 が理解できません。

1

なぜ、h - i + 1になるのですか? なぜ、 h - iではダメなのですか?

2

ぼんやりと頭に浮かんでいる気がするのですが、ぼやけすぎていて、全くわかりません。
 (i-1)*2+1;iに数を代入してみたら、ちゃんと表示すべき個数になるということは、わかったのですが、なぜ、この式になるのですか?

じっくりねっとり解説お願いします><

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 5

+3

まず、ピラミッドの絵を描いてみましょう。こういう問題は、絵を見ながら考えると判りやすいですからね。

□□□■
□□■■■
□■■■■■

空白文字を使うと、回答のどこが空白文字なのかが判りずらいので、上の図では空白文字(" ")の代わりに □ 、アスタリスク("*")の代わりに■を使っています。

この絵をプログラムで書くには
下の行(プログラムで後で書き出す行)ほど、最初に出力する空白文字の数は少なくする。(1ずつ減る)
下の行(プログラムで後で書き出す行)ほど、その後に出力する"*"の数は多くする。(2ずつ増える)
という事がわかるかと思います。
*が2ずつ多くするのは、左右対称な三角形にするためです。

ここで、プログラムの構造を見てみると、次のような構造になっています。
・外側のForループは、出力する行を制御します。 (hが行の総数(高さ)、iが現在印刷中の行)
・内側の1つめのForループは、空白文字を印刷します。 (jが何個目の空白文字かを示す)
・内側の2つめのForループは、アスタリスクを印刷します。 (jが何個目の空白文字かを示す)

== ここから、質問への直接の回答です ==
1)内側の1つ目のForループについて
/* なぜ、h-i+1 なのか? なぜ、h-i じゃないのか? */

これは「一番下の段(3段目)の左側に空白文字を置くかどうか」によって決まります。
h-i+1ではなく、h-iとすれば、下のようなピラミッドが書かれることになりますが、これもピラミッドが書かれているので正しいプログラムです。 左側にもっと多くの空白が欲しければ、h-i+3とかすれば良いです。

□□■
□■■■
■■■■■

どんな出力が良いか(好きか)は、好みの問題ですから自由にして良いと思います。(h-i,h-i+1,h-i+2,h-i+3、どれでも正解です(^o^)

1)内側の2つ目のForループについて
左右対称のピラミッドにするためには、ある行には、その上の行で出力したアスタリスクに、左右それぞれ一つのアスタリスクを付け加えたものを出力する必要があります。
1つ目のForループで、空白文字の数が下にいくほど減っていますから、2つ目のループでは出力するアスタリスクの数を2つずつ増やしていけばOKということになります。

その計算をしている式が、for分の中の  (i-1)*2+1 です。
(i-1)*2+1 = (i*2) - 1 と変形できます。(分配法則)
i*2で、1行したに行く毎にアスタリスクの数が2つ増えます。
-1 で、最初の行(ピラミッドの頂上)のアスタリスクの数を1にしています(1行目(i=1)の時に、i*2-1=1になりますから)

(i-1)*2+1を(i-1)*2に変えると、頂上のアスタリスクが2個のピラミッドになります(下図)。
これも正解だと思いますが、頂上のアスタリスクを1つにしたほうがピラミッドらしいですね。

□□□■■ 
□□■■■■ 
□■■■■■■

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/21 17:52

    ありがとうございます!!
    一番わかりやすかったです!!!!
    助かりました!!!

    キャンセル

checkベストアンサー

+2

h-i+1について

左に必ず最低1つは空白を確保しておきたいからですかね?
左詰めでよければ+1しなくてもいいような気がします。

(i-1)*2+1について

00100:1個
01110:3個
11111:5個
という図は中心から左右対称です。
中心の縦の1ラインとその左右と3分割して考えてみてください。
(左側)
00:1個の左側は0個
01:3個の左側は1個
11:5個の左側は2個
(中央)
1:1個の中央は1個
1:3個の中央は1個
1:5個の中央は1個
(右側)
00:1個の右側は0個
10:3個の右側は1個
11:5個の右側は2個
式「(i-1)*2+1」の(i-1)は左右に必要な個数になります。
iが1、つまり1段目は左側に0個、右側に0個(iが1なら0が欲しい)
2段目(iが2)なら左に1個、右に1個(iが2なら1が欲しい)
*2なのは左と右の2つで1セットなので2倍にしています。
最後の+1は中央の分が常に1個あるので+1している、という具合。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/21 17:51

    ありがとうございます!
    一番納得できました!
    助かりました!!!

    キャンセル

+1

1

h-i+1 を h-i、h-i+5、h-i+10 などに変えて実行してみると意味が解るのではないでしょうか。

2

ピラミッドを上から1段目、2段目・・・n段目と数えるとします。
この場合各段の * の数は・・・

1段目・・・1個
2段目・・・3個
3段目・・・5個
(続く)

となりますね。この段数と * の個数には増え方にパターンがあることが解るでしょうか?
各段の * の個数を計算式で書くと・・・

1段目・・・2x0+1=1個
2段目・・・2x1+1=3個
3段目・・・2x2+1=5個
(続く)

上記のように書けますね。つまり・・・

n段目・・・2x(n-1)+1

というように書くことができるわけです。
質問にあったコードでは段数を変数 i で表していますよね。

(i-1)*2+1 

これは・・・

2*(i-1)+1

と書くことができ、これは上で書いた式(太文字部分)と同じであることがお判りいただけますでしょうか。
ちなみに、質問の中に「なぜこのような式になるのか」とありますが、*の増え方のパターンを太文字のような式で表すことができる、ということを見いだすことこそが、アルゴリズムを考え出すということではないでしょうか。

ご参考になれば。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/21 17:53

    ありがとうございます!!!
    とてもわかりやすかったです!!
    助かりました!!!

    キャンセル

0

i, j共に1からスタートしているからです。+1を入れておかないと0段の処理をすることになってしまいます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/21 17:48

    ありがとうございます。

    キャンセル

0

このぐらいの問題なら、i, j, h に具体的な数字を入れて紙の上に1ステップずつお絵かきすれば理解しやすいんじゃないかな

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/21 17:48

    ありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.49%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C

    3805questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • アルゴリズム

    420questions

    アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。