关于杨辉三角,相信你们都很熟悉,忘记的同窗请自行Wiki。下面引用一张 Wiki 上的图做为知识回顾。编程
上面这张图能够简要归纳出如下几点:数组
1.每行数左右对称,且都是以1开始和结束的正整数。spa
2.行数递增的同时,列数也在递增。3d
3.两条斜边上的1除外,其它的元素值均由其上部两个数之和。code
首先来看一下运行结果的截图:blog
如上图,这是一个如下三角(直角三角形)的形式打印出来的,观察上面这张图,很容易就会令人联想到用一个矩阵来存储全部的数值,打印的时候只打印下三角便可。ip
第1步:首先构建一个10x10的矩阵get
第2步:观察发现列下标为0的元素都为1,且行列下标值相等的元素也都为1数学
第3步:其他元素都可由 array[i][j] = array[i-1][j] + array[i-1][j-1] 计算获得it
开始编写代码:【C语言实现】
void PrintTriangle() { int arr[10][10]={0}; int i,j; for(i=0;i<10;i++) { for(j=0;j<=i;j++) { if(j==0 || i==j) arr[i][j]=1; else arr[i][j]=arr[i-1][j]+arr[i-1][j-1]; printf("%-4d", arr[i][j]); } printf("\n"); } }
如今,咱们固定了数组的大小。若是咱们想拥有一个能够经过输入,选择打印行数的的方法,怎么办呢?把方法改成 PrintTriangle(int n) { int arr[n][n]={0}; ... } 不幸的是,这段代码在 C 中编译没法经过,由于 C 语言中数组定义要求的是一个常量表达式。
那么,咱们换成 C# 来试试:
static void PrintTriangle(int n) { int[,] arr = new int[n, n]; int i, j; for (i = 0; i < arr.GetLength(0); i++) { for (j = 0; j <= i; j++) { if (j == 0 || i == j) arr[i, j] = 1; else arr[i, j] = arr[i - 1, j] + arr[i - 1, j - 1]; Console.Write(arr[i, j].ToString().PadRight(3)); } Console.WriteLine(); } }
使人欣慰的是 C# 没有编译错误,咱们彻底能够在 C# 中使用变量定义数组。为何 C# 支持而 C 不支持呢?这个已经超出本文的主旨了,有兴趣的同窗能够搜索相关资料。
如今,咱们来思考另外一个问题:咱们只使用了一半的数组空间,而另外一半却白白浪费掉了,实在惋惜。有没有一种方式,可让咱们直接计算出相关元素的值,而无需用数组来作临时存储呢?为了阅读方便,我把上面的图贴在此处,仔细观察,是否能够用数学计算来表示每一个元素的值。
如今以列做为单位来观察其中的规律,每次循环进来都会首先打印 1,那么,咱们就能够在每次内层循环进入的时候打印出 1,解决第1列。
第2列参考循环中 i,j 值得变化,刚好 i-j 是第2列的值。
第3列,继续来验证并总结这个规律,想啊想,想啊想。数学没学好,是硬伤啊。。呵呵
你想到了吗?^_^ 【C】
void PrintTriangle(int n) { int num, i, j; for(i=0; i < n; i++) { num = 1; for(j=0; j <= i; j++) { printf("%-3d ", num); num = num * (i-j)/(j+1); } printf("\n"); } }
是的,重点就是这个:num = num * (i-j)/(j+1) 。
最后,咱们来看另外一种实现方式:
1
=======
1 1
1 1
-----------
1 2 1
=======
1 2 1
1 2 1
-------------
1 3 3 1
以此类推,咱们只要在第2行开始,对 11 进行移位后相加运算就能够了。
看一段 Python 的实现:
def triangle(n): row = [1] k = [0] for x in range(n): print row row = [l+r for l,r in zip(row+k, k+row)]