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

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

新規登録して質問してみよう
ただいま回答率
85.50%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

4回答

5443閲覧

ピラミッド

ryohasegawa

総合スコア437

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

1グッド

0クリップ

投稿2016/04/13 15:08

編集2016/04/14 15:46

解決しました。プログラムは以下です。アドバイスをくださった方ありがとうございました。とても感謝しています。

C++

1#include "stdafx.h" 2#include <iostream> 3 4using namespace std; 5 6int main() 7{ 8 int x; 9 cout << "入力した数の応じてピラミッドを作ります。\n";//プログラムの説明 10 11 do { //繰り返し開始 12 cout << "数字を入力してください。"; //入力を促す 13 cin >> x; //入力してもらう 14 } while (x <= 0); //入力した数字が1より大きければループからぬけ出す 15 16 for (int i = 1; i <= x; i++) { //周回(改行)のfor文 17 for (int j = 0; j <= x - 1 - i; j++) //空白を作る 18 cout << "_"; 19 for (int t = 1; t <= i * 2 - 1 ; t++) //ピラミッドを作る 20 cout << "*"; 21 cout << "\n";} //改行 22 23 ::system("pause"); //実行結果をすぐに消さないようにする 24} 25

============================================================
追加2少しアドバイスをもらって、改行をするたびにスペースが1つ減り、☆が2つずつ増えているのがわかりあした。
そこでプログラムを書いてみたのですが、毎回空欄が生成されます。これはどうすればいいでしょうか?

C++

1#include "stdafx.h" 2#include <iostream> 3 4using namespace std; 5 6int main() 7{ 8 int x; 9 cout << "入力した数の応じてピラミッドを作ります。\n"; 10 11 do { 12 cout << "数字を入力してください。"; 13 cin >> x; 14 } while (x <= 0); 15 int q = x; 16 17 for (int i = 0; i <= x; i++) { 18 for (int t = 1; t <= i * 2 - 1 ; t++){ 19 for (int j = 0; j <= q - 1; j++) 20 cout << "_"; 21 cout << "*"; 22 } 23 cout << "\n"; 24 q--; 25 26 }::system("pause"); 27}

======================以前========================

追加です。参考にさせてもらって、じぶんなりに作ってみたんですが、実行すると一行目は入力した数よりひとつ少なく空欄(_)は入り一つ*が入って改行すると成功するのですが、2行目のはじめの空欄を一つ減らしたあとから、ズレが生じます。
この解決はどうすればいいのですか?

C++

1#include "stdafx.h" 2#include <iostream> 3 4using namespace std; 5 6int main() 7{ 8 int x; 9 cout << "入力した数の応じてピラミッドを作ります。\n"; 10 11 do { 12 cout << "数字を入力してください。"; 13 cin >> x; 14 } while (x <= 0); 15 x -= 1; 16 int q = x; 17 18 cout << x << "\n"; 19 20 for (int i = 0; i <= x; i++) { 21 for (int t = 0; t <= i; t++){ 22 for (int j = 1; j <= q - 1; j++) 23 cout << "_"; 24 cout << "*"; 25 } 26 cout << "\n"; 27 q--; 28 }::system("pause"); 29}

=====================以前==========================

入力した数のピラミッドを作る問題を説いています。
そこでfor文を使ってやるのですがわかりません。
回答を教えて下さい。

C++

1for (int i = 1; i <= x; i += 2) { 2 for (int t = 1; t <= i; t++){ 3 for (int j = 1; j <= q - 1; j++) { 4 cout << "_"; 5 q--; 6 } 7 cout << "*"; 8 } 9 cout << "\n"; 10 }

これを考えたのですが、うまく行きません。
それと、コマンド画面が表示された時にCtrl+F5を押しているんですが画面がすぐに閉じてしまいます。

mhashi👍を押しています

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

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

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

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

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

guest

回答4

0

cpp

1#include "stdafx.h"

いらない。Visual Studioをお使いのようなので、プロジェクトを作るときは「空のプロジェクト」を選びましょう

cpp

1using namespace std;

やめよう

で本題。

まず*を任意個数出力する関数を作りましょう。つまり

cpp

1void print_n_char(std::size_t n, char c) 2{ 3 for(std::size_t i = 0; i < n; ++i) std::cout << c; 4}

ですね。(operatorのオーバーロードを使えばもっと綺麗に書けるんですがそれはもっとC++ができるようになってからの話ですね)

さて、

____* ___*** __***** _******* *********

_は空白

を出力したいのでした。ということは一行ずつ見ると、今の行番号をi(0起算),全行数をnとすると

  1. 空白をn - i - 1個出力
  2. *(i + 1) * 2 - 1個出力

すればいいとわかります。あとは実現するだけですね。

cpp

1void print(size_t n) 2{ 3 for(size_t i = 0; i < n; ++i){ 4 print_n_char(n - i - 1, ' '); 5 print_n_char((i + 1) * 2 - 1, '*'); 6 std::cout << std::endl; 7 } 8}

こんなかんじですね。

あとは組み合わせるだけです。なお今回は入力チェックは簡略化してますがまじめにやるなら
C++で再帰しつつnoexceptな数値入力関数を作る - Qiita#成果物
このくらいやりましょう。

cpp

1int main() 2{ 3 const size_t n = [](){ size_t in; std::cin >> in; return in; }(); 4 print(n); 5 return 0; 6}

Wandboxでの実行結果がこちら
http://melpon.org/wandbox/permlink/R7DTT3FstJRnIswa

わからないところあったら言ってください。

ちなみにoperatorのオーバーロードを使うというのはどういうことかというと
http://melpon.org/wandbox/permlink/3SVR8WfO2mVl5soh
こういうことです。

投稿2016/04/14 14:09

編集2016/04/14 14:20
yumetodo

総合スコア5850

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

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

yumetodo

2016/04/14 14:12 編集

ちなみに ::system("pause"); は環境依存(Windowsでしかうごかない)ので個人的にはあまりおすすめしないです。コマンドプロンプトで pause /? とするとなにをしているかわかると思います。つまりC++が持っている機能ではありません。今回はいいですが、環境依存だということを覚えていてくだい
guest

0

これを考えたのですが、うまく行きません。

それと、コマンド画面が表示された時にCtrl+F5を押しているんですが画面がすぐに閉じてしまいます。

main()関数の最後 return 0; で抜ける前に、

c

1 ::system("pause");

を入れておけば、コンソール画面が閉じる前に表示したままになります。何かキーを押せば画面が閉じてプログラムが終了します。

投稿2016/04/14 09:35

PineMatsu

総合スコア3579

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

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

ryohasegawa

2016/04/14 09:47

終了しないようになりました、ありがとうございました。感謝します!
guest

0

ベストアンサー

こんにちは。

頭休めに作ってみました。起動したら入力待ちになるので、ピラミッドの高さを入力してEnterを押して下さい。

C++

1#include <iostream> 2#include <string> 3using namespace std; 4int main() 5{ 6 unsigned h; 7 cin >> h; 8 for (unsigned i=0; i < h; ++i) 9 cout << string(h-i-1, ' ') << string(i*2+1, '*') << "\n"; 10 return 0; 11}

それと、コマンド画面が表示された時にCtrl+F5を押しているんですが画面がすぐに閉じてしまいます。

Visual Studioの編集画面(プログラムを開始する前)の時にCtrl+F5を押して下さい。
なお、デバッグモード実行ではないので注意です。(ブレークを設定していても止まりません。)


この問題ってときどき出てくるようですが、何かの問題なのでしょうか?
下記もありました。
C++ ピラミッド

因みに、上記も「c言語 while文で直角三角形を*で描く」も求めているものは中央に山があるピラミッドです。
teratailの仕様でベタ書きだとインデントつけてもそれが全て無視されるのです。
3連のバッククォーテーション・マークで囲めば良いのですが、なかなか気が付かない人が多いのです。

投稿2016/04/14 09:05

編集2016/04/14 09:11
Chironian

総合スコア23272

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

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

ryohasegawa

2016/04/14 09:50

柴田望洋さんのC++のテキストのfor文の問題で、左寄せのピラミッド * ** *** **** このような感じや   *  *** ***** このようなピラミッドなどの問題が出題されるんです。 この4月から高校生の自分にはまだ早いのでしょうか?w
Chironian

2016/04/14 09:54

なるほど、教えてくれてありがとう。 決して早くないと思いますよ。頑張って下さい。
PineMatsu

2016/04/14 10:02

実用的じゃないので授業の宿題のような気がしますね。そういう意味では答えを教えるのはあまりよろしくないかも(笑)
Chironian

2016/04/14 10:24

PineMatsuさん。 真正面からの「回答を教えて下さい。」がなんとなく好ましかったのでつい。
ryohasegawa

2016/04/14 10:26

追加させてもらったことがあるので、お願いします
Chironian

2016/04/14 10:40

考え方を整理する必要がありそうです。 まず、手で実際に書いてみると良いかも知れません。 例えば5と入力した時の正解はなんでしょう? ____* ___*** __***** _******* ********* それとも、これとは異なるイメージでしょうか? ____* ___*_* __*___* _*_____* *_______* どうもこの2つがごっちゃになってしまってないでしょうか? どちらか決めて、それぞれの行毎に_を出力する回数と*を出力する回数を書いてみてください。 そして、その数字を発生できるようにfor文の構成を考えてみて下さい。
tkturbo

2016/04/14 11:30

ちなみにピラミッド問題はjavaでも見たことがあります。 制御構文の学習にちょうどいいのではないかと。
Chironian

2016/04/14 12:35

> 制御構文の学習にちょうどいいのではないかと。 なるほど。確かにそうですね。
ryohasegawa

2016/04/14 13:31

____* ___*** __***** _******* ********* これをしたいのですが、紙に書いて考えたけっか、下の ____* ___*_* __*___* _*_____* *_______* を考えているように見えたのかもしれません。
Chironian

2016/04/14 13:45

例えば5の時の_と*の数を数えてみてください。     _ * 1行目 4 1 2行目 3 3 3行目 2 5 4行目 2 7 5行目 0 9 何か見えてきません? また、下記では「_が幾つかと*(例えば__*)」が複数出力されますよ。 (例えば__*__*) for (int t = 0; t <= i; t++){  for (int j = 1; j <= q - 1; j++)   cout << "_";  cout << "*"; }
ryohasegawa

2016/04/14 14:14 編集

自分で考えたのは、全体の周回(改行の回数を☆にプラスしていけばいいんですかね?) そういう問題ではないですかね? 自分の頭がおかしくなってきましたw
ryohasegawa

2016/04/14 14:23

アドバイスをもらいプログラムを作ってみました。 すると少し近づきました。 ありがとうございます。 あともう少しふんばらないと行けないみたいです。
Chironian

2016/04/14 14:27

プログラミングの世界へようこそ!! 後少しのようですね。頑張って下さい。
ryohasegawa

2016/04/14 14:36

毎回空白が作成されてしまうんですがなぜでしょう? 一度初期化されているのでしょうか?
Chironian

2016/04/14 15:07

A for (int t = 1; t <= i * 2 - 1 ; t++){ AB for (int j = 0; j <= q - 1; j++) AB  cout << "_"; A  cout << "*"; A } 最初のfor (int t = 1;...のループは行頭にAをつけた範囲を繰り返し実行します。 次のfor (int j = 0;...のループは次にBをつけた範囲を繰り返し実行します。 5を入力した場合、2行目ではi=2、q=3になってますね。 すると、Aのループはfor (int t = 1; t <= 3; t++)となるので3回実行します。 そして、Bのループはfor(int j =0; j <= 2; j++)となるので3回実行します。 その結果、___*___*___*と出力されます。 ループの形を変えて下記のようにしたら、___***と出力されるようになりますよ。 B for (int j = 0; j <= q - 1; j++) B  cout << "_"; A for (int t = 1; t <= i * 2 - 1 ; t++){ A  cout << "*"; A }
ryohasegawa

2016/04/14 15:43

解決できました! 助かりました。
guest

0

投稿2016/04/13 23:12

cateye

総合スコア6851

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

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

ryohasegawa

2016/04/14 07:56

左端に寄せてのピラミッドを作るんじゃなく、中央揃えのピラミッドを作りたいんです。
tkturbo

2016/04/14 12:14

「中央揃えのピラミッドを作りたい」←そこを考えないとだめなのでは?>ryohasegawaさん
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問