最近,看一些东西突然碰到了杨辉三角,有点懵,故查了点资料,
首先看一下杨辉三角形式:
首先,要想编程解决杨辉三角,必先了解其性质:
上述那么多,我们真正需要的也就是第一个,每个数等于它上方两数之和。
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 100typedef 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 pythondef 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