作者VictorTom (鬼翼&娃娃鱼)
看板C_and_CPP
标题Re: [问题] 请问画一个图形
时间Tue Oct 27 01:06:20 2009
※ 引述《fjf1980 (Yes We Can!)》之铭言:
: 我今天无聊自己玩画一个图形,就是给定高及宽都是奇数,画一个类似以下图形
: 1 ***********
: 2 ***** *****
: 3 **** ****
: 4 *** ***
: 5 ** **
: 6 * *
: 7 ** **
: 8 *** ***
: 9 **** ****
: 10***** *****
: 11***********
: 花了我好久时间,写出来一个程式,但是感觉真的是很逊的程式
: 在底下,请问有没有高手能对这图形有比较好的写法
比较好的写法小弟不清楚, 但是看到这题不知道为什麽就手很痒....
然後就写了一个有点恶心加些恶搞的版本, 字串加递回胡搞瞎搞版XD
==
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSTAR 79
int length = 21;
void print_star(char *StarLine, char *StarLeft, char *StarRight, int level)
{
char StarPrint[MAXSTAR] = { 0 };
int left = length/2+1, right = length/2;
strncat(StarPrint, StarLeft, left);
strncat(StarPrint, StarRight, right);
printf("%s\n", StarPrint);
if(level >= length/2) return;
else print_star(StarLine, StarLeft+1, StarRight-1, level+1);
printf("%s\n", StarPrint);
StarPrint[0] = '\0';
}
int main(void)
{
char *StarLeft, *StarRight;
char StarLine[MAXSTAR*2] = { 0 };
int i, j;
for(i=0; i<=length/2; ++i) StarLine[i] = '*';
StarLeft = &StarLine[0];
for(i=length/2+1, j=0; j<length-2; ++j) StarLine[i+j] = ' ';
StarRight = &StarLine[i+j+1];
for(i=i+j, j=0; j<length/2+1; ++j) StarLine[i+j] = '*';
StarLine[i+j] = '\0';
print_star(StarLine, StarLeft, StarRight, 0);
system("PAUSE");
return 0;
}
==
感觉应该可以再省掉几个变数, length在不超过MAXSTAR的情况下可以改....
因为偷懒所以没有做奇偶数检查, 跑到console的最大奇数宽79还不会爆喔:)
==
简单的说, main函数在产生一个特殊的char string - StarLine[];
接着设定一左一右两个指标指着它, 然後递回边印边移动指标送....
Ex: length = 11 时....
[length-2的' '] / [左右各为length/2+1的'*']
StarLine[]内容为: "****** ******"
^ ^
左指标 右指标(右指指在右半第二个*没错喔)
递回每一轮, 从左指标印length/2+1个char, 从右指标印length/2个char....
於是就刚好印出: [左]"******"[右]"*****" => "***********"
这里我用strncat()做是因为不用回圈我不知道怎麽指定印N个char....Orz
print_star()里的StarPrint正好就拿来当strncat()的temp....
自己有一份独立的空间好处是後面下半部就可以直接印(stack没爆的话~_~)
印完以後递回呼叫时, 左指标右移一个char, 右指标左移一个char....
於是第二轮会印: [左]"***** "[右]"*****" => "***** *****"
然後第三轮会印: [左]"**** "[右]" ****" => "**** ****"
印到第length/2+1层的时候递回就不需要再呼叫下去了....
(其实这里也可以用右指标-左指标>=length-2来判断, 但懒得改了^^||)
==
说恶搞, 也不过是把印的回圈藏在strncat里....
把上下对称反转的部份藏在递回里cover掉啦....
一开始的发想是总觉得"****** ******"这东西好像可以利用....
然後想一想, 推一推, 画画图, 还被左右*怎麽对称与不对称卡了好久....
最後又把递回给加上去就变成这付德性了, 还请大大们鞭小力一点<(_ _)>
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 220.132.174.98
※ 编辑: VictorTom 来自: 220.132.174.98 (10/27 01:06)
1F:→ VictorTom:递回终止照文章()里写的有错, 反正推一下就有了XDD 10/27 01:25
Edit: 忘了用BBSCode标色工具, 补用一下....@_@"
※ 编辑: VictorTom 来自: 220.132.174.98 (10/27 01:50)
2F:推 fjf1980:V大真的太强了@@ 这是我无聊想到的一个图形 想写写看 10/27 08:59
3F:→ fjf1980:但我写不出来V大 还有上面另一位高手的漂亮写法呀 >"< 10/27 08:59
4F:→ VictorTom:s大的写法才是比较简单的写法, 小弟这写法只是在搞怪XD 10/27 09:00
5F:→ VictorTom:主要的想法是, 这图形里左右上下对称(不考虑奇数中间), 10/27 09:01
6F:→ VictorTom:怎麽把做印'*'与印' '判断的地方有效率的"写成code":) 10/27 09:02
7F:→ VictorTom:即, 找出规律, 合并相关算式, 然後组合成像s大那样@_@" 10/27 09:03
8F:→ VictorTom:如果有些其他(奇怪)的idea, 就是努力实作看看如何罗^^ 10/27 09:05
9F:推 fjf1980:我觉得这就是逻辑思考好坏的差别 我逻辑差 所以写不好 >"< 10/27 09:06
10F:→ VictorTom:小弟我觉得这种能力是可以训练的, 多做多练习些题目应该 10/27 09:13
11F:→ VictorTom:会比较有感觉(像ACM?), 虽然可能和那些聪明的不能比Q_Q~ 10/27 09:14
12F:→ VictorTom:总觉得那些去参加比赛的人都利害到不知该崇拜还是敬畏^^ 10/27 09:16