最近,看一些东西突然碰到了杨辉三角,有点懵,故查了点资料,
首先看一下杨辉三角形式:
首先,要想编程解决杨辉三角,必先了解其性质:
上述那么多,我们真正需要的也就是第一个,每个数等于它上方两数之和。
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #include<cstdio> #include<iostream> using namespace std; long long int Triangle[1000][1000]; int main() { Triangle[1][1]=1; //初始化 Triangle[2][1]=1;Triangle[2][2]=1; for ( int i=3;i<=50;i++) //制作三角。 { for ( int j=1;j<=i;j++) { Triangle[i][j]=Triangle[i-1][j-1]+Triangle[i-1][j]; } } for ( int i=1;i<=50;i++) //输出 { for ( int j=1;j<=i;j++) { cout<<Triangle[i][j]<< " " ; } cout<<endl; } return 0; } |
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | class Program { public int yanghui( int value) { if (value<3) return 1; int [,]arry= new int [value,value]; Console.WriteLine( "数组为:" ); for ( int i=0;i<value;i++) { string str= "" ; str=str.PadLeft(value-i); Console.Write(str); for ( int j=0;j<=i;j++) { if (i==j||j==0) arry[i,j]=1; else arry[i,j]=arry[i-1,j-1]+arry[i-1,j]; Console.Write(arry[i,j]+ "" ); } Console.WriteLine(); } } static void Main( string []args) { Program p= new Program(); Console.WriteLine( "请输入数组值:" ); if (p.yanghui(Convert.ToInt16(Console.ReadLine()))) Console.WriteLine( "输入数值必须大于3" ); Console.Readkey(); } } |
C 以下的代码均用标准 C 语言写成,可以被包括 MSVC(含 VC6)、GCC 的多种 C 编译器编译。 这个算法使用只行列位置和左侧的数值算出数值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /* yh-rt1.c - 时间和空间最优算法 */ #include <stdio.h> #include <stdlib.h> int main() { int s = 1, h; // 数值和高度 int i, j; // 循环计数 scanf ( "%d" , &h); // 输入层数 printf ( "1\n" ); // 输出第一个 1 for (i = 2; i <= h; s = 1, i++) // 行数 i 从 2 到层高 { printf ( "1 " ); // 第一个 1 for (j = 1; j <= i - 2; j++) // 列位置 j 绕过第一个直接开始循环 //printf("%d ", (s = (i - j) / j * s)); printf ( "%d " , (s = (i - j) * s / j)); printf ( "1\n" ); // 最后一个 1,换行 } getchar (); // 暂停等待 return 0; } |
默认状态下不启用金字塔和菱形的输出 默认求直角三角形,可通过注释的开关或使用编译器的 -D 定义开关调节等腰三角形和菱形输出。如果觉得复杂,可按照 define 使用的情况剔除因不符合 ifdef 条件从而未启用的代码之后阅读。 这个算法创建了一个二维数组,并且通过上一行的数值求当前行。在反过来再次打印时,这个程序会使用以前算好的值,从而节省了重复迭代的时间。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | /* yh-2d.c - 二维数组迭代 */ #include<stdio.h> #define M 10 // 行数 // #define PYRAMID // 金字塔,会额外填充空格 // #define REVERSE // 反向再来一次,得到菱形 int main( void ) { int a [M][M], i, j; // 二维数组和循环变量,a[行][列] for (i = 0; i<M; i++) // 每一行 { #ifdef PYRAMID for (j = 0;j <= M-i; j++) printf ( " " ); #endif // 填充结束 for (j = 0; j <= i; j++) // 赋值打印 printf ( "%4d" , (a[i][j] = (i == j || j == 0) ? 1 : // 首尾置 1 a[i - 1][j] + a[i - 1][j - 1] )); // 使用上一行计算 printf ( "\n" ); } #ifdef REVERSE for (i = M-2; i >= 0; i--) { #ifdef PYRAMID for (j = 0;j <= M - i; j++) printf ( " " ); #endif // 填充结束 for (j = 0;j <= i; j++) printf ( "%4d" ,a[i][j]); // 直接使用以前求得的值 printf ( "\n" ); } #endif // 菱形结束 getchar (); // 暂停等待 } |
这一个使用大数组写成,风格更接近教科书上的 VC6 代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /* yh-rt3.c - 较为暴力的大数组 */ #include <stdio.h> #include "string.h" int main() { int a[10000]; //容器,由n*(n+1)/2<=10000可知,n<=141 int b,CR,i; //b为当前行数,CR为要求显示的行数,i为循环数 printf ( "请输入要显示的行数(3~141):" ); scanf ( "%d" ,&CR); YHSJ(CR); a[1]=a[2]=1; //前两行数值少且全为1,故直接输出 printf ( "%d\n" ,a[1]); printf ( "%d %d\n" ,a[1],a[2]); for (b=3;b<=CR;b++) //从第三行开始判断 { for (i=b;i>=2;i--) //从倒数第一个数开始加 a[i]=a[i]+a[i-1]; //杨辉三角的规律,没有值的数组默认为0 for (i=1;i<=b;i++) //显示循环 printf ( "%d " ,a[i]); printf ( "\n" ); // 换行 } return 0; } |
这个版本使用队列的方式输出。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | #include <stdio.h> #include <stdlib.h> #define EMPTY 1 #define OFLOW 2 #define INVAL 3 #define MAX_Q 100 typedef int DataType; // 数据类型选择 typedef struct { DataType elem[MAX_Q]; int front, rear; } LinkQ; // 队列及检查宏 #define InitQ(Q) LinkQ Q; Q.front=Q.rear=-1; #define _EQ(Q,e) Q.elem[(Q.rear=(Q.rear+1)%MAX_Q)]=e #define EnQ(Q,e) if((Q.rear+1)%MAX_Q==Q.front) Exit(OFLOW,"Overflow"); _EQ(Q,e) #define DeQ(Q,e) e=Q.elem[(Q.front=(Q.front+1)%MAX_Q)] #define Front(Q) Q.elem[(Q.front+1)%MAX_Q] // 退出 int Exit( int err, char msg[]) { puts (msg); exit (err); return err; } int main( void ){ int n=1,i,j,k,t; InitQ(Q); printf ( "please enter a number:" ); scanf ( "%d" ,&n); if (n<=0) { printf ( "ERROR!\n" ); exit (INVAL); } for (i=0;i<n;i++) printf ( " " ); puts ( "1" ); EnQ(Q,1); EnQ(Q,1); for (i=1;i<n;i++) { for (k=0;k<n-i;k++) printf ( " " ); EnQ(Q,1); for (j=0;j<i;j++){ DeQ(Q,t); printf ( "%3d " ,t); EnQ(Q,t+Front(Q)); } EnQ(Q,1); DeQ(Q,t); printf ( "%d\n" ,t); } return 0; } |
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | public class TriangleArray { public static void main(String[] args) { final int NMAX = 10 ; // allocate triangular array int [][] odds = new int [NMAX + 1 ][]; for ( int n = 0 ; n <= NMAX; n++) odds[n] = new int [n + 1 ]; // fill triangular array for ( int n = 0 ; n < odds.length; n++) for ( int k = 0 ; k < odds[n].length; k++) { /* * compute binomial coefficient n*(n-1)*(n-2)*...*(n-k+1)/(1*2*3*...*k) */ int lotteryOdds = 1 ; for ( int i = 1 ; i <= k; i++) lotteryOdds = lotteryOdds * (n - i + 1 ) / i; odds[n][k] = lotteryOdds; } // print triangular array for ( int [] row : odds) { for ( int odd : row) System.out.printf( "%4d" , odd); System.out.println(); } } } |
PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <?php /* 默认输出十行,用T(值)的形式可改变输出行数 */ class T{ private $num ; public function __construct( $var =10) { if ( $var <3) die ( "值太小啦!" ); $this ->num= $var ; } public function display(){ $n = $this ->num; $arr = array (); //$arr=array_fill(0,$n+1,array_fill(0,$n+1,0)); $arr [1]= array_fill (0,3,0); $arr [1][1]=1; echo str_pad ( " " , $n *12, " " ); printf( "%3d" , $arr [1][1]); echo "<br/>" ; for ( $i =2; $i <= $n ; $i ++){ $arr [ $i ]= array_fill (0,( $i +2),0); for ( $j =1; $j <= $i ; $j ++){ if ( $j ==1) echo str_pad ( " " ,( $n +1- $i )*12, " " ); printf( "%3d" , $arr [ $i ][ $j ]= $arr [ $i -1][ $j -1]+ $arr [ $i -1][ $j ]); echo " " ; } echo "<br/>" ; } } } $yh = new T(); //$yh=new T(数量); $yh ->display(); ?> |
只输出数组的方式如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?php $max = 10; $L = [1]; var_dump( $L ); $L = [1,1]; var_dump( $L ); $n = 2; while ( $n <= $max - 1){ $oldL = $L ; $L [ $n ] = 1; $n ++; for ( $i = 1; $i < count ( $oldL ); $i ++){ $L [ $i ] = $oldL [ $i -1] + $oldL [ $i ]; } var_dump( $L ); } ?> |
Python 较为便捷,代码量较少的实现方式如下:
1 2 3 4 5 6 7 8 | # -*- coding: utf-8 -*- #!/usr/bin/env python def triangles(): L = [ 1 ] while True : yield L L.append( 0 ) L = [L[i - 1 ] + L[i] for i in range ( len (L))] |
该方式用到了列表生成式,理解起来较困难,下面是另一种方式:
1 2 3 4 5 6 7 8 | def triangles(): ret = [ 1 ] while True : yield ret for i in range ( 1 , len (ret)): ret[i] = pre[i] + pre[i - 1 ] ret.append( 1 ) pre = ret[:] |
杨辉三角还有可以通过以下方式完成
第一行,就是(a+b)0 = 1a0b0 = 1
第二行,就是(a+b)1 =1a1b0 +1a0b1
第三行,就是 (a+b)2 =1a2b0 + 2a1b1 +1a0b2
第四行,就是(a+b)3 = 1a3b0 +3a2b1 + 3a1b2+1a0b3
第五行,就是(a+b)4 =1a4b0 + 4a3b1 +6a2b2 + 4a3b1 +1a4b0
(a+b)^n=C(n,0)a^n+C(n,1)a^(n-1)*b+C(n,2)a^(n-2)*b^2+…+C(n,n)b^n