C語(yǔ)言畫(huà)謝賓斯基三角形
謝賓斯基三角形是一個(gè)有意思的圖形,(英語(yǔ):Sierpinski triangle)是一種分形,由波蘭數(shù)學(xué)家謝爾賓斯基在1915年提出,它是一種典型的自相似集。
先畫(huà)一個(gè)三角形,然后呢,取三角形的中點(diǎn),組成一個(gè)新的三角形,把新的三角形挖空。
依次遞歸,就出現(xiàn)了后面的那個(gè)圖形。
如果用C語(yǔ)言來(lái)畫(huà)一個(gè)這樣的三角形,我們需要怎么畫(huà)呢?
我們先看看這樣一段代碼,思路還是跟之前一樣,在屏幕上畫(huà)出一個(gè)矩形,x行和y列。
#include#include #include #define SIZE (1 << 5)/*64*/ /* 毫秒級(jí) 延時(shí) */ void msleep(int ms) { struct timeval delay; delay.tv_sec = 0; delay.tv_usec = ms * 1000; // 20 ms select(0, NULL, NULL, NULL, &delay); } int main() { int x, y, i; printf("%d\n",SIZE); /*y用來(lái)控制列數(shù)*/ for (y = SIZE - 1; y >= 0; y--, msleep(20),putchar('\n')) { /*控制行輸出*/ for (i = 0; i < y; i++) {msleep(20);putchar('^');} } return 0; }
代碼輸出
為了方便大家觀看,我做了一些調(diào)整
為了測(cè)試,我把代碼改成這樣,方便大家看到輸出。
#include#define SIZE (1 << 3) int main() { int x, y, i; printf("%d\n",SIZE); /*y用來(lái)控制列數(shù)*/ for (y = SIZE - 1; y >= 0; y--,putchar('\n')) { /*控制行輸出*/ for (i = 0; i < y; i++) {putchar('^');} for (x = 0; x + y < SIZE; x++){ putchar('#'); } } return 0; }
代碼輸出
weiqifa@bsp-ubuntu1804:~/c$ gcc shengdanshu.c && ./a.out 8 ^^^^^^^# ^^^^^^## ^^^^^### ^^^^#### ^^^##### ^^###### ^####### ######## weiqifa@bsp-ubuntu1804:~/c$
這里可以好好分析一下
y 長(zhǎng)度是用來(lái)控制輸出多少行,可以看到一共有 8 行。
i 的長(zhǎng)度是用來(lái)輸出 ^ 字符的,這個(gè)字符隨著 y的減少也會(huì)相應(yīng)減小。
x 也受到y(tǒng) 的限制,主要是在另一半輸出 # 號(hào)字符。
知道了上面,我們來(lái)看看核心代碼
#include#define SIZE (1 << 3) int main() { int x, y, i; printf("%d\n",SIZE); /*y用來(lái)控制列數(shù)*/ for (y = SIZE - 1; y >= 0; y--,putchar('\n')) { /*控制行輸出*/ for (i = 0; i < y; i++) {putchar('^');} for (x = 0; x + y < SIZE; x++){ printf((x & y) ? " " : "*"); } } return 0; }
代碼輸出
8 ^^^^^^^* ^^^^^^** ^^^^^* * ^^^^**** ^^^* * ^^** ** ^* * * * ********
已經(jīng)有了我們題目上所的三角形的模樣了,這里只要再稍微修改下,就可以得到我們題目中所的那樣的三角形了。不對(duì)稱的原因主要是因?yàn)?strong>字符高度是寬度的兩倍。
代碼修改成這樣
#include#define SIZE (1 << 3) int main() { int x, y, i; printf("%d\n",SIZE); /*y用來(lái)控制列數(shù)*/ for (y = SIZE - 1; y >= 0; y--,putchar('\n')) { /*控制行輸出*/ for (i = 0; i < y; i++) {putchar('^');} for (x = 0; x + y < SIZE; x++){ printf((x & y) ? " " : "* "); } } return 0; }
代碼輸出
weiqifa@bsp-ubuntu1804:~/c$ gcc shengdanshu.c && ./a.out 8 ^^^^^^^* ^^^^^^* * ^^^^^* * ^^^^* * * * ^^^* * ^^* * * * ^* * * * * * * * * * * * weiqifa@bsp-ubuntu1804:~/c$
然后我們把 ^ 字符替換成空格,也就是我們想要的東西了。
然后空格和 * 的字符輸出,主要是靠 x & y 來(lái)控制的,他們又是如何控制的呢?
我們計(jì)算一下上面的算法
綠色的地方是我們輸出 * 字符的位置,藍(lán)色的 是我們輸出 空格的位置,空格是兩個(gè)空格,所以就出現(xiàn)了我們看到的那樣。
我們?cè)傩薷南麓a
#include#define SIZE (1 << 5) int main() { int x, y, i; printf("%d\n",SIZE); /*y用來(lái)控制列數(shù)*/ for (y = SIZE - 1; y >= 0; y--,putchar('\n')) { /*控制行輸出*/ for (i = 0; i < y; i++) {putchar(' ');} for (x = 0; x + y < SIZE; x++){ printf((x & y) ? " " : "* "); } } return 0; }
代碼輸出
weiqifa@bsp-ubuntu1804:~/c$ gcc shengdanshu.c && ./a.out 32 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * weiqifa@bsp-ubuntu1804:~/c$
這樣看起來(lái)是不是很酷了。
我在我的另一個(gè)號(hào)里面用這樣方法畫(huà)了一個(gè)圣誕樹(shù),我覺(jué)得也挺有意思的,喜歡的同學(xué)可以看看,當(dāng)時(shí)寫(xiě)那個(gè)代碼的時(shí)候是圣誕夜,我們剛好在開(kāi)會(huì),覺(jué)得有點(diǎn)無(wú)聊。
鏈接如下
如何用 C 語(yǔ)言畫(huà)一個(gè)「圣誕樹(shù)」?
知乎上的大神畫(huà)圣誕樹(shù),基礎(chǔ)理論也是基于這個(gè),后續(xù)剖析一下,我覺(jué)得非常有意思。
附上幾張謝賓斯基三角形的圖片
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!