看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《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)
VictorTom:遞迴終止照文章()裡寫的有錯, 反正推一下就有了XDD 10/27 01:25
Edit: 忘了用BBSCode標色工具, 補用一下....@_@" ※ 編輯: VictorTom 來自: 220.132.174.98 (10/27 01:50)
fjf1980:V大真的太強了@@ 這是我無聊想到的一個圖形 想寫寫看 10/27 08:59
fjf1980:但我寫不出來V大 還有上面另一位高手的漂亮寫法呀 >"< 10/27 08:59
VictorTom:s大的寫法才是比較簡單的寫法, 小弟這寫法只是在搞怪XD 10/27 09:00
VictorTom:主要的想法是, 這圖形裡左右上下對稱(不考慮奇數中間), 10/27 09:01
VictorTom:怎麼把做印'*'與印' '判斷的地方有效率的"寫成code":) 10/27 09:02
VictorTom:即, 找出規律, 合併相關算式, 然後組合成像s大那樣@_@" 10/27 09:03
VictorTom:如果有些其他(奇怪)的idea, 就是努力實作看看如何囉^^ 10/27 09:05
fjf1980:我覺得這就是邏輯思考好壞的差別 我邏輯差 所以寫不好 >"< 10/27 09:06
VictorTom:小弟我覺得這種能力是可以訓練的, 多做多練習些題目應該 10/27 09:13
VictorTom:會比較有感覺(像ACM?), 雖然可能和那些聰明的不能比Q_Q~ 10/27 09:14
VictorTom:總覺得那些去參加比賽的人都利害到不知該崇拜還是敬畏^^ 10/27 09:16