谢宾斯基三角形是一个有意思的图形,(英语:Sierpinski triangle)是一种分形,由波兰数学家谢尔宾斯基在1915年提出,它是一种典型的自相似集。
先画一个三角形,然后呢,取三角形的中点,组成一个新的三角形,把新的三角形挖空。
依次递归,就出现了后面的那个图形。
如果用C语言来画一个这样的三角形,我们需要怎么画呢?
我们先看看这样一段代码,思路还是跟之前一样,在屏幕上画出一个矩形,x行和y列。
#include <stdio.h>
#include <time.h>
#include <sys/select.h>#define SIZE (1 << 5)/*64*//* 毫秒级 延时 */
void msleep(int ms)
{struct timeval delay;delay.tv_sec = 0;delay.tv_usec = ms * 1000; // 20 msselect(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 <stdio.h>#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 <stdio.h>#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 <stdio.h>#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 <stdio.h>#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 语言画一个「圣诞树」?
知乎上的大神画圣诞树,基础理论也是基于这个,后续剖析一下,我觉得非常有意思。
附上几张谢宾斯基三角形的图片
参考:
[1]https://www.cnblogs.com/lfri/p/10128073.html
[2]https://codegolf.stackexchange.com/questions/6281/draw-a-sierpinski-triangle/6292#6292
推荐阅读:
专辑|Linux文章汇总
专辑|程序人生
专辑|C语言
我的知识小密圈