*でバッテン(×) を表示する

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
kerotan0820
記事: 91
登録日時: 9年前
住所: 東京都
連絡を取る:

*でバッテン(×) を表示する

#1

投稿記事 by kerotan0820 » 8年前

学校の課題として、バッテンを作るプログラムが出題されました。

完成すれば良い、と言われたので、取り急ぎ完成はさせたのですが、プログラムが汚くて困っています。

こちらです。

コード:

#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 などの無駄な変数がきになる)

ご教示お願いします。
けろけろにゃー (」・ω・)」うー!

hss12
記事: 40
登録日時: 8年前

Re: *でバッテン(×) を表示する

#2

投稿記事 by hss12 » 8年前

課題に条件はあるのでしょうか。
これが一番美しいと思いますが。

コード:

#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] ? "*" : " ");
で良かった。
最後に編集したユーザー hss12 on 2011年11月16日(水) 05:36 [ 編集 1 回目 ]

アバター
pooka
記事: 7
登録日時: 9年前
住所: 福井

Re: *でバッテン(×) を表示する

#3

投稿記事 by pooka » 8年前

こんなかんじとか。

コード:

#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;
}
規則性を見つけられるとスッキリと書けるかと思います。

hss12
記事: 40
登録日時: 8年前

Re: *でバッテン(×) を表示する

#4

投稿記事 by hss12 » 8年前

そこまでやるならこれでどうだ。(笑)

コード:

#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;
}
まあ、ぱっと見、何をしているのか分からないので
短ければ良いってものでもないですね。

non
記事: 1097
登録日時: 9年前

Re: *でバッテン(×) を表示する

#5

投稿記事 by non » 8年前

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;
}
non

non
記事: 1097
登録日時: 9年前

Re: *でバッテン(×) を表示する

#6

投稿記事 by non » 8年前

次に上半分と下半分は上下対称です。ですから、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;
}
non

non
記事: 1097
登録日時: 9年前

Re: *でバッテン(×) を表示する

#7

投稿記事 by non » 8年前

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;
}
non

アバター
bitter_fox
記事: 607
登録日時: 9年前
住所: 大阪府

Re: *でバッテン(×) を表示する

#8

投稿記事 by bitter_fox » 8年前

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;
}


アバター
a5ua
記事: 199
登録日時: 9年前

Re: *でバッテン(×) を表示する

#9

投稿記事 by a5ua » 8年前

再帰呼び出しを使って、ループをなくしてみました。

コード:

#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;
}

アバター
kerotan0820
記事: 91
登録日時: 9年前
住所: 東京都
連絡を取る:

Re: *でバッテン(×) を表示する

#10

投稿記事 by kerotan0820 » 8年前

沢山の回答有難うございます。
多すぎて驚いてしまいました…。

そして様々なテクニックが使われたスマートなプログラムが沢山で目が点です…。

皆様が紹介してくださった多くのプログラムの中で、なんとか理解出来そうな

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;
}
こちらのプログラムを参考にして完成させたいと思います。
コピペしても意味が無いので、とりあえず参考にして私のプログラムを書き換えてみたいと思います。

再帰呼び出しを使ったプログラムなどはハードルが私には高すぎるので、提出するプログラムがまとまり次第、再起呼び出しの勉強をした上で、再度確認してみたいと思います。

本当に沢山の回答有難うございます。
プログラムを無事書き換えることが出来ましたら、解決としたいので、しばらく保留とさせて頂きたいと思います。
それでは、頑張ってきます。
けろけろにゃー (」・ω・)」うー!

初級者
記事: 200
登録日時: 9年前

Re: *でバッテン(×) を表示する

#11

投稿記事 by 初級者 » 8年前

こんなアプローチの仕方もありかな、と。

コード:

#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;
}

beatle
記事: 1280
登録日時: 8年前
住所: 埼玉
連絡を取る:

Re: *でバッテン(×) を表示する

#12

投稿記事 by beatle » 8年前

そういえば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(); };
        }
    }
}

アバター
kerotan0820
記事: 91
登録日時: 9年前
住所: 東京都
連絡を取る:

Re: *でバッテン(×) を表示する

#13

投稿記事 by kerotan0820 » 8年前

解決しました。
ありがとうございました。
けろけろにゃー (」・ω・)」うー!

閉鎖

“C言語何でも質問掲示板” へ戻る