楊輝三角問題

楊輝三角形也叫賈憲三角形,西方叫帕斯卡三角形,其實就是各階二項式係數排列起來構成的三角形,如下。每行的數字實際上是(a + b) ^ n展開後的結果。

          1 
         1 1 
        1 2 1 
       1 3 3 1 
      1 4 6 4 1

歷史上發現這個三角形的人很多,這裏介紹幾個主要的,北宋人賈憲約1050年首先使用“賈憲三角”進行高次開方運算。楊輝,字謙光,南宋時期杭州人。在他1261年所著的《詳解九章算法》一書中,輯錄瞭如上所示的三角形數表,稱之爲“開方作法本源”圖。歐洲直到1623年以後,法國數學家帕斯卡在13歲時發現了“帕斯卡三角”。

編程輸出楊輝三角形

方法一

使用二維數組計算並存儲各行數字然後輸出,如果不考慮每行左側空格的話,上面的三角形可以寫成如下形式

1

1 1

1 2 1

1 3 3 1

1 4 6 4 1

根據觀察我們發現,第一列和對角線上的數字都是1,其他數字則是其左上方數字和正上方數字之和,如下圖,其中數字1被標記成紅色,因爲1是我們預先設置好的,圖中的白色數字爲合成數字,合成數字是由1或者其他已經存在的數字相加而成的。比如數字2是由其上方的1和左上方的1相加而成,第一個3是由其上方的2和左上方的1相加而成。

設p是存儲數字的二維數組,設i和j分別表示p的行號和列號,則有

  • 如果j == 0 或 j == i,則p[i][j] = 1 ;
  • 否則,p[i][j] = p[i - 1][j] + p[i - 1][j - 1] ;

有了上面的分析,寫代碼就不再是難事了。

複製代碼
// 打印楊輝三角形,參數n是層數 void YanghuiTriangle(int n) { //定義二維數組並初始化 int **p = new int*[n] ; for(int i = 0; i < n; ++i) { p[i] = new int[n] ; for(int j = 0; j < n; ++j) p[i][j] = 0 ; } // 填充並輸出 for(int i = 0; i < n; ++i) { for(int j = 0; j <= i; ++j) { // 第一列和對角線列的元素置1 if(j == 0 || j == i) p[i][j] = 1 ; // 其他元素是其上方元素和左上方元素之和 else p[i][j] = p[i - 1][j] + p[i - 1][j - 1] ; cout << p[i][j] << " " ; } cout << endl ; } }
複製代碼

輸出如下

方法二

方法一的優點是直觀,代碼好寫,但是缺點是如果層數n很大的話,那麼將需要很大的存儲空間(n * n),而這麼大的空間中有一半被浪費掉了。下面這個方法使用一維數組實現,空間上只要n即可。思路是逐行計算並輸出,舉個例子,假設我們要輸出5行(n = 5),我們先計算並輸出第一行,然後計算並輸出第二行,...,最後是第五行,因爲每行的數字個數不超過行數n,所以一個含有n個元素的一維數組就可以勝任了,只不過這個一維數組中的數字是不斷變化的(除了第一個元素),我們用新增的元素覆蓋掉了原來的元素。下圖展示了這個一維數組的變化過程。其中紅色字數字表示每次迭代新增的數字。可見這種方法中第一列數字1始終保持不變。

1 首先定義一個含有n個元素的一維數組,且第一個元素初始化爲1,其他元素初始化爲0

2 對於每一行的計算,除了第一元素之外,其他所有元素都由其本身的值加上其前一個值構成,注意,計算的方向是從後向前,如果從前向後的話,元素本來的值將被覆蓋。

代碼如下

複製代碼
// 打印楊輝三角形,參數n是層數 void YanghuiTriangle(int n) { // 定義一個一維數組 int* a = new int[n] ; for (int i = 0; i < n; ++i) a[i] = 0 ; a[0] = 1 ; for (int i = 0; i < n; ++i) { // 計算當前行的數字,注意要從後向前計算,否則會覆蓋以前的值 for (int j = i; j > 0; --j) a[j] += a[j - 1]; // 打印空格 for (int j = 0; j < n - i; ++j) cout << " " ; // 打印數字 for (int j = 0; j < i + 1; ++j) cout << a[j] << " " ; cout << endl ; } }
複製代碼
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章