🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

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

アルゴリズム

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

Q&A

解決済

5回答

28121閲覧

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

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

アルゴリズム

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

0グッド

0クリップ

投稿2016/04/21 07:45

c

1#include <stdio.h> 2int main(){ 3 int i, j, h; 4 printf("何段? : "); 5 scanf("%d", &h); 6 7 for (i = 1; i <= h; i++) { 8/* 1 */ for (j = 1; j <= h-i+1; j++) { /* なぜ、h-i+1 なのか? なぜ、h-i じゃないのか? */ 9 putchar(' '); 10 } 11/* 2 */ for (j = 1; j <= (i-1)*2+1; j++) { /* 理解不能(>皿<) */ 12 putchar('*'); 13 } 14 putchar('\n'); 15 } 16 17 18 return 0; 19}

12 が理解できません。

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

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

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

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

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

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

この絵をプログラムで書くには
下の行(プログラムで後で書き出す行)ほど、最初に出力する空白文字の数は少なくする。(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 = (i2) - 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 08:34

coco_bauer

総合スコア6915

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/04/21 08:52

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

0

ベストアンサー

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 08:12

HiroshiWatanabe

総合スコア2160

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/04/21 08:51

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

0

###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 08:44

tkanda

総合スコア2425

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/04/21 08:53

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

0

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

投稿2016/04/21 08:10

WoodenHamlet

総合スコア306

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/04/21 08:48

ありがとうございます。
guest

0

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

投稿2016/04/21 07:58

PineMatsu

総合スコア3579

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/04/21 08:48

ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問