C言語関係掲示板

過去ログ

No814 アスタリスクを菱形に表示する

[戻る] [ホームページ]
No.10311

for反復構造のネストについて
投稿者---youhei(2003/11/06 01:19:14)


今、forループをネストして、アスタリスクを菱形に表示するためのプログラムを下記のように書いているのですが、無駄に長いような気がします。お手数ですが、もっと無駄のない書き方があれば教えていただけないでしょうか?よろしくお願いします。

#include<stdio.h>

main()
{
  int i, k, n = 5;

  /* 上半分 */

  for (k = 1; k <= n ; k++) {
    for (i = 1; i <= n - k; i++) {   /* 左空白n - k個 */
      printf(" ");
    }
    for (i = 1; i <= k; i++) {       /* 左半分k個 */
      printf("*");
    }
    for (i = 1; i <= k - 1; i++) {   /* 右半分k - 1個 */
      printf("*");
    }
    printf("\n");
  }

  /* 下半分 */

  for (k = 1; k <= n - 1; k++) {
    for (i = 1; i <= k; i++) {       /* 左空白k個 */
      printf(" ");
    }
    for (i = n - k; i >= 1; i--){    /* 左半分n - k個 */
      printf("*");
    }
    for (i = n - k - 1; i >= 1; i--) { /* 右半分n - k - 1個 */
      printf("*");
    }
    printf("\n");
  }
    
  return 0;
}



No.10313

Re:for反復構造のネストについて
投稿者---YuO(2003/11/06 01:44:51)


>今、forループをネストして、アスタリスクを菱形に表示するためのプログラムを下記のように書いているのですが、無駄に長いような気がします。
>お手数ですが、もっと無駄のない書き方があれば教えていただけないでしょうか?よろしくお願いします。

どちらかというと,数学に近いかもしれませんが……。

まず,左側の空白の個数について。
i段目の空白の個数は,n - iの絶対値になります。
これは下半分でも変わりません。

次に,アスタリスクについて。
菱形の幅は,左右の空白も含めると常に2n - 1です。
そして,左右の空白の個数は常に等しいです。
よって,アスタリスクは,2n - 1からn - iの絶対値の2倍を引いた数になります。

これをプログラムすればよいです。


ちなみに,絶対値はstdlib.hにabsという関数があるので,これを使うのが楽です。
#自分で定義しても大した手間ではないですが。

また,空白は,
http://www.catnet.ne.jp/kouno/c_faq/c12.html#10
をちょこっと変更すると,ループ無しで出力できるようになります。
#残念ながら,「任意の文字」をn文字出力する機構はない。


No.10342

Re:Re:
投稿者---youhei(2003/11/06 23:12:56)


標準ライブラリ関数を調べるとint abs(int j);というものがありました。それと、C FAQ に書いてあるprintf(%*d);の使い方に関しては、基本のことなのにまったく思いつけず、そういえばそうだと、おもわず可笑しくなってきました。絶対値を利用するほうは勉強不足で、ご迷惑をおかけしました。早くこの掲示板で役に立てるように、がんばっていこうと思います。ありがとうございました。

No.10319

Re:for反復構造のネストについて
投稿者---かずま(2003/11/06 13:19:43)


同じ処理を繰り返すときは関数にするのも手です。

void p(int n, int c) { while (n--) putchar(c); }

int main(void)
{
    int i, n = 5;
    for (i = 1; i < n; i++) p(n-i, ' '), p(i*2-1, '*'), p(1, '\n');
    for (i = n; i > 0; i--) p(n-i, ' '), p(i*2-1, '*'), p(1, '\n');
    return 0;
}

for 文をひとつにしたければ、

    for (i = 1-n; i < n; i++)
        p(abs(i), ' '), p((n-abs(i))*2-1, '*'), p(1, '\n');


No.10343

Re:Re:
投稿者---youhei(2003/11/06 23:23:46)


この関数の使い方は面白いです。これによって、文章のほうが大変簡略化され、気持ちがいいです。for文の凝縮のほうは、少し難しいですが、何とかものにしたいと思います。ご返答どうもありがとうございました。