谢宾斯基三角形是一个有意思的图形,(英语:Sierpinski triangle)是一种分形,由波兰数学家谢尔宾斯基在1915年提出,它是一种典型的自相似集。
先画一个三角形,然后呢,取三角形的中点,组成一个新的三角形,把新的三角形挖空。
依次递归,就出现了后面的那个图形。
如果用C语言来画一个这样的三角形,我们需要怎么画呢?
我们先看看这样一段代码,思路还是跟之前一样,在屏幕上画出一个矩形,x行和y列。
#include #include #include #define SIZE (1 << 5)/*64*/ /* 毫秒级 延时 */ 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用来控制列数*/ for (y = SIZE - 1; y >= 0; y--, msleep(20),putchar('\n')) { /*控制行输出*/ for (i = 0; i < y; i++) {msleep(20);putchar('^');} } return 0; }
代码输出
为了方便大家观看,我做了一些调整
为了测试,我把代码改成这样,方便大家看到输出。
#include #define SIZE (1 << 3) int main() { int x, y, i; printf("%d\n",SIZE); /*y用来控制列数*/ 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 长度是用来控制输出多少行,可以看到一共有 8 行。
i 的长度是用来输出 ^ 字符的,这个字符随着 y的减少也会相应减小。
x 也受到y 的限制,主要是在另一半输出 # 号字符。
知道了上面,我们来看看核心代码
#include #define SIZE (1 << 3) int main() { int x, y, i; printf("%d\n",SIZE); /*y用来控制列数*/ 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 ^^^^^^^* ^^^^^^** ^^^^^* * ^^^^**** ^^^* * ^^** ** ^* * * * ********
已经有了我们题目上所的三角形的模样了,这里只要再稍微修改下,就可以得到我们题目中所的那样的三角形了。不对称的原因主要是因为字符高度是宽度的两倍。
代码修改成这样
#include #define SIZE (1 << 3) int main() { int x, y, i; printf("%d\n",SIZE); /*y用来控制列数*/ 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 来控制的,他们又是如何控制的呢?
我们计算一下上面的算法
绿色的地方是我们输出 * 字符的位置,蓝色的 是我们输出 空格的位置,空格是两个空格,所以就出现了我们看到的那样。
我们再修改下代码
#include #define SIZE (1 << 5) int main() { int x, y, i; printf("%d\n",SIZE); /*y用来控制列数*/ 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$
这样看起来是不是很酷了。
我在我的另一个号里面用这样方法画了一个圣诞树,我觉得也挺有意思的,喜欢的同学可以看看,当时写那个代码的时候是圣诞夜,我们刚好在开会,觉得有点无聊。
链接如下
如何用 C 语言画一个「圣诞树」?
知乎上的大神画圣诞树,基础理论也是基于这个,后续剖析一下,我觉得非常有意思。
附上几张谢宾斯基三角形的图片