ページ 1 / 1
*でバッテン(×) を表示する
Posted: 2011年11月16日(水) 02:22
by kerotan0820
学校の課題として、バッテンを作るプログラムが出題されました。
完成すれば良い、と言われたので、取り急ぎ完成はさせたのですが、プログラムが汚くて困っています。
こちらです。
コード:
#include<stdio.h>
int main(void)
{
int mloop;
int space,space2=2,cspace,cspace2=5;
/*********上半分出力*********/
for(mloop=0;mloop<3;mloop++) //メインループ(mloop)
{
for(space=0;space<mloop;space++) //スペース0で始まってmloop(行数)分スペース表示
printf(" ");
printf("*"); //*出力
for(cspace=cspace2;cspace>0;cspace--)
printf(" ");
cspace2-=2; //次ループ次の中央スペースの数を2減らす。
printf("*");
printf("\n"); //改行
}
/*********中央*出力*********/
printf(" *");
printf("\n");
/*********下半分出力*********/
cspace2=1;
for(mloop=0;mloop<3;mloop++) //メインループ(mloop)
{
for(space=space2;space>0;space--) //スペース0で始まってmloop(行数)分スペース表示
printf(" ");
space2-=1;
printf("*"); //*出力
for(cspace=0;cspace<cspace2;cspace++)
printf(" ");
cspace2+=2; //次ループ次の中央スペースの数を2増やす。
printf("*");
printf("\n"); //改行
}
}
バッテンの上半分
中央の一つ
バッテンの下半分
この3つのパーツに分けて出力しています。
先頭のスペースの数の増減
中央のスペースの数の増減
これらにあわせてアスタリスク、スペースを表示させるforループの回数を変動させています。
これで表示はされるものの、もう少し、綺麗にできないでしょうか。
例えばちょっとした数式を使うだとか…。(cspace2、space2 などの無駄な変数がきになる)
ご教示お願いします。
Re: *でバッテン(×) を表示する
Posted: 2011年11月16日(水) 03:41
by hss12
課題に条件はあるのでしょうか。
これが一番美しいと思いますが。
コード:
#include<stdio.h>
int main(void)
{
puts("* *");
puts(" * * ");
puts(" * * ");
puts(" * ");
puts(" * * ");
puts(" * * ");
puts("* *");
return 0;
}
または一度配列に入れてみるとか。
コード:
#include<stdio.h>
#define MAX 7
int main(void)
{
int i,j;
int x[MAX][MAX]={0};
for(i=0, j=MAX-1; i<MAX; i++, j--){
x[i][i]=1;
x[i][j]=1;
}
for(i=0; i<MAX; i++){
for(j=0; j<MAX; j++){
printf("%s", x[i][j] ? "*" : " ");
}
printf("\n");
}
return 0;
}
追記
コード:
"%s"書かなくても
printf(x[i][j] ? "*" : " ");
で良かった。
Re: *でバッテン(×) を表示する
Posted: 2011年11月16日(水) 04:13
by pooka
こんなかんじとか。
コード:
#include <stdio.h>
#define NUM 7
int main(void)
{
int i, j;
for(i = 0; i < NUM; i++){
for(j = 0; j < NUM; j++){
printf(((i == j) || (NUM - i - 1 == j)) ? "*" : " ");
}
printf("\n");
}
return 0;
}
規則性を見つけられるとスッキリと書けるかと思います。
Re: *でバッテン(×) を表示する
Posted: 2011年11月16日(水) 06:08
by hss12
そこまでやるならこれでどうだ。(笑)
コード:
#include <stdio.h>
#define NUM 7
int main(void)
{
int i, j;
for(i=0; i<NUM; i++){
for(j=0; j<NUM+1; j++){
printf((j<NUM) ? (((i==j)||(NUM-i-1==j)) ? "*" : " ") : "\n");
}
}
return 0;
}
まあ、ぱっと見、何をしているのか分からないので
短ければ良いってものでもないですね。
Re: *でバッテン(×) を表示する
Posted: 2011年11月16日(水) 09:15
by non
kerotan0820 さんが書きました:例えばちょっとした数式を使うだとか…。(cspace2、space2 などの無駄な変数がきになる)
ご教示お願いします。
まず、大きさを変えられるように、
#define N 3 のように定義しましょう。
何行目(mloopの値)を書いているかによって、csapce2やspace2は決まりますので、式にします。
なるべく元の形を生かして書き直しました。
コード:
#include<stdio.h>
#define N 3
int main(void)
{
int mloop;
int space,cspace;
/*********上半分出力*********/
for(mloop=0;mloop<N;mloop++) //メインループ(mloop)
{
for(space=0;space<mloop;space++) //スペース0で始まってmloop(行数)分スペース表示
printf(" ");
printf("*"); //*出力
for(cspace=2*(N-mloop)-1;cspace>0;cspace--)
printf(" ");
//cspace2-=2; //次ループ次の中央スペースの数を2減らす。
printf("*");
printf("\n"); //改行
}
/*********中央*出力*********/
//printf(" *");
for(mloop=N;mloop>0;--mloop)
printf(" ");
printf("*\n");
/*********下半分出力*********/
//cspace2=1;
for(mloop=0;mloop<N;mloop++) //メインループ(mloop)
{
for(space=N-mloop-1;space>0;space--) //スペース0で始まってmloop(行数)分スペース表示
printf(" ");
//space2-=1;
printf("*"); //*出力
for(cspace=0;cspace<2*mloop+1;cspace++)
printf(" ");
//cspace2+=2; //次ループ次の中央スペースの数を2増やす。
printf("*");
printf("\n"); //改行
}
return 0;
}
Re: *でバッテン(×) を表示する
Posted: 2011年11月16日(水) 09:22
by non
次に上半分と下半分は上下対称です。ですから、mloopのforカウントを
上半分のとき
for(mloop=0;mloop<N;mloop++)
なら、下半分のときは
for(mloop=N-1;mloop>=0;mloop--)
にしてあげると、このforの中身は上半分と下半分がまったく同じになります。
コード:
#include<stdio.h>
#define N 3
int main(void)
{
int mloop;
int space,cspace;
/*********上半分出力*********/
for(mloop=0;mloop<N;mloop++) //メインループ(mloop)
{
for(space=0;space<mloop;space++) //スペース0で始まってmloop(行数)分スペース表示
printf(" ");
printf("*"); //*出力
for(cspace=2*(N-mloop)-1;cspace>0;cspace--)
printf(" ");
printf("*");
printf("\n"); //改行
}
/*********中央*出力*********/
for(mloop=N;mloop>0;--mloop)
printf(" ");
printf("*\n");
/*********下半分出力*********/
for(mloop=N-1;mloop>=0;mloop--) //メインループ(mloop)
{
for(space=0;space<mloop;space++) //スペース0で始まってmloop(行数)分スペース表示
printf(" ");
printf("*"); //*出力
for(cspace=2*(N-mloop)-1;cspace>0;cspace--)
printf(" ");
printf("*");
printf("\n"); //改行
}
return 0;
}
Re: *でバッテン(×) を表示する
Posted: 2011年11月16日(水) 09:28
by non
forの中身が同じになったのだから、関数にしましょう。
また、cspaceはspaceを使えば、無駄な変数が減ります。
コード:
#include<stdio.h>
#define N 3
void disp_line(int mloop)
{
int space;
for(space=0;space<mloop;space++) //スペース0で始まってmloop(行数)分スペース表示
printf(" ");
printf("*"); //*出力
for(space=2*(N-mloop)-1;space>0;space--)
printf(" ");
printf("*");
printf("\n"); //改行
}
int main(void)
{
int mloop;
/*********上半分出力*********/
for(mloop=0;mloop<N;mloop++) //メインループ(mloop)
disp_line(mloop);
/*********中央*出力*********/
for(mloop=N;mloop>0;--mloop)
printf(" ");
printf("*\n");
/*********下半分出力*********/
for(mloop=N-1;mloop>=0;mloop--) //メインループ(mloop)
disp_line(mloop);
return 0;
}
Re: *でバッテン(×) を表示する
Posted: 2011年11月16日(水) 11:23
by bitter_fox
printfをうまく使えばループは一つで済みます。
コード:
#include <stdio.h>
#include <math.h>
#define N 3
int main()
{
int i;
for (i = 0; i < N * 2 + 1; i++)
{
printf("%*s%*s\n", (N - abs(N - i) + 1) * 2, "*", abs(N - i) * 2 * 2, i == N ? "" : "*");
}
return 0;
}
Re: *でバッテン(×) を表示する
Posted: 2011年11月16日(水) 14:48
by a5ua
再帰呼び出しを使って、ループをなくしてみました。
コード:
#include <stdio.h>
#define SPACE " "
#define STAR "*"
void print_parts(int n, const char *s)
{
if (n >= 1) {
printf("%s", s);
print_parts(n - 1, s);
}
}
void print_line(int n, int i)
{
print_parts(i, SPACE);
print_parts(1, STAR);
print_parts(2 * (n - i) - 1, SPACE);
print_parts(1, STAR);
putchar('\n');
}
void print_center(int n)
{
print_parts(n, SPACE);
print_parts(1, STAR);
putchar('\n');
}
void print_x_rec(int n, int i)
{
if (i == n) {
print_center(i);
} else {
print_line(n, i);
print_x_rec(n, i + 1);
print_line(n, i);
}
}
void print_x(int n)
{
print_x_rec(n, 0);
}
int main(void)
{
print_x(3);
return 0;
}
Re: *でバッテン(×) を表示する
Posted: 2011年11月16日(水) 17:08
by kerotan0820
沢山の回答有難うございます。
多すぎて驚いてしまいました…。
そして様々なテクニックが使われたスマートなプログラムが沢山で目が点です…。
皆様が紹介してくださった多くのプログラムの中で、なんとか理解出来そうな
poookaさん、hss12さんのこちらのプログラム
コード:
#include <stdio.h>
#define NUM 7
int main(void)
{
int i, j;
for(i = 0; i < NUM; i++){
for(j = 0; j < NUM; j++){
printf(((i == j) || (NUM - i - 1 == j)) ? "*" : " ");
}
printf("\n");
}
return 0;
}
コード:
#include <stdio.h>
#define NUM 7
int main(void)
{
int i, j;
for(i=0; i<NUM; i++){
for(j=0; j<NUM+1; j++){
printf((j<NUM) ? (((i==j)||(NUM-i-1==j)) ? "*" : " ") : "\n");
}
}
return 0;
}
この2つを目標として、提出するプログラムは
nonさんが教えてくださった、
コード:
#include<stdio.h>
#define N 3
int main(void)
{
int mloop;
int space,cspace;
/*********上半分出力*********/
for(mloop=0;mloop<N;mloop++) //メインループ(mloop)
{
for(space=0;space<mloop;space++) //スペース0で始まってmloop(行数)分スペース表示
printf(" ");
printf("*"); //*出力
for(cspace=2*(N-mloop)-1;cspace>0;cspace--)
printf(" ");
printf("*");
printf("\n"); //改行
}
/*********中央*出力*********/
for(mloop=N;mloop>0;--mloop)
printf(" ");
printf("*\n");
/*********下半分出力*********/
for(mloop=N-1;mloop>=0;mloop--) //メインループ(mloop)
{
for(space=0;space<mloop;space++) //スペース0で始まってmloop(行数)分スペース表示
printf(" ");
printf("*"); //*出力
for(cspace=2*(N-mloop)-1;cspace>0;cspace--)
printf(" ");
printf("*");
printf("\n"); //改行
}
return 0;
}
こちらのプログラムを参考にして完成させたいと思います。
コピペしても意味が無いので、とりあえず参考にして私のプログラムを書き換えてみたいと思います。
再帰呼び出しを使ったプログラムなどはハードルが私には高すぎるので、提出するプログラムがまとまり次第、再起呼び出しの勉強をした上で、再度確認してみたいと思います。
本当に沢山の回答有難うございます。
プログラムを無事書き換えることが出来ましたら、解決としたいので、しばらく保留とさせて頂きたいと思います。
それでは、頑張ってきます。
Re: *でバッテン(×) を表示する
Posted: 2011年11月16日(水) 21:05
by 初級者
こんなアプローチの仕方もありかな、と。
コード:
#include <stdio.h>
void draw(int n)
{
int x, y;
for (y = -n; y <= n; y++) {
for (x = -n; x <= n; x++) {
putchar((y == x || y == -x) ? '*' : ' '), putchar(' ');
}
putchar('\n');
}
putchar('\n');
}
int main(void)
{
int i;
for (i = 1; i <= 10; i++) {
draw(i);
}
return 0;
}
Re: *でバッテン(×) を表示する
Posted: 2011年11月16日(水) 23:34
by beatle
そういえばC言語っていう指定はされてないなと思ってC++で書いてみました。
コード:
#include <iostream>
#include <deque>
#include <algorithm>
#include <iterator>
#include <functional>
using namespace std;
int main()
{
const char x_str0[] = "* ";
deque<char> x_str(begin(x_str0), end(x_str0) - 1);
function<void ()> rotate = [&](){ x_str.push_front(x_str.back()); x_str.pop_back(); };
auto cout_iter = ostream_iterator<char>(cout);
for (size_t i = 0; i < 2 * x_str.size() - 1; ++i)
{
copy(x_str.begin(), x_str.end(), cout_iter);
copy(x_str.rbegin() + 1, x_str.rend(), cout_iter);
cout.put('\n');
rotate();
if (x_str.back() == '*')
{
rotate = [&](){ x_str.push_back(x_str.front()); x_str.pop_front(); };
}
}
}
Re: *でバッテン(×) を表示する
Posted: 2011年11月18日(金) 07:27
by kerotan0820
解決しました。
ありがとうございました。