關於楊輝三角,相信你們都很熟悉,忘記的同窗請自行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)]