打印杨辉三角&二项式展开式各项系数
(a + b)2
= a2 + 2ab + b2
展开式各项系数为1 2 1
(a + b)3
= a3 + 3a2b + 3ab2 + b3
展开式各项系数为1 3 3 1
(a + b)4
= a4 + 4a3b + 6a2b2 + 4ab3 + b4
展开式各项系数为1 4 6 4 1
(a + b)5
……
……
(a + b)n =
杨辉三角:
每行两侧永远是 1,中间每个数都是它头顶左右两个数之和
C语言实现
法一:数学排列组合公式法
使用数学排列组合数公式法,是通过阶乘运算来求得每行数据的
特点: 使用了数学公式和子函数
缺点: 多次嵌套 for 循环,时间复杂度较大,阶乘数太大,有行数限制
#include <stdio.h>
long Comb(int m, int n){ //求组合数子函数
long mFactorial = 1;
long n_mFactorial = 1;
if(m == 0)
return 1;
else if(m == n)
return 1;
else{
for(int i = n - m + 1; i <= n; i++)
n_mFactorial *= i;
for(int i = 1; i <= m; i++)
mFactorial *= i;
return (n_mFactorial / mFactorial);
}
}
int main(){
int N;
printf("请输入所要打印的杨辉三角的行数(1~13): ");
scanf("%d",&N);
for(int i = 0; i < N; i++){
for(int j = N - 1 - i; j >= 1; j--)printf(" ");
for(int j = 0; j <= i; j++)
printf("% ld ",Comb(j, i));
putchar('\n');
}
return 0;
}
调试:打印行数限制在13行以内,大于13行结果不正确,原因是阶乘的数太大,超出了整型的数据存储范围
法二:找规律法,二维数组,通俗易懂
上面已经提到了规律:每行两侧永远是 1,中间每个数都是它头顶左右两个数之和。借助这个规律来打印杨辉三角,可以节省很多算力,时间复杂度较低
#include <stdio.h>
int main(){
int N;
int a[24][24];
a[0][1] = 1;
for(int i = 0; i < 24; i++)a[i][0] = 0;
for(int i = 1; i < 24; i++)a[i][i+1] = 0;
printf("请输入打印杨辉三角的行数(1~23):");
scanf("%d",&N);
for(int i = 1; i <= N; i++){
for(int j = N - i; j > 0; j--)printf(" ");
for(int j = 1; j <= i; j++){
a[i][j] = a[i-1][j-1] + a[i-1][j];
printf(" %7d",a[i][j]);
}
putchar('\n');
}
return 0;
}
运行:
法三:法二优化,一维数组
从法二中推导出一个简化的算法,放入一维数组中
#include <stdio.h>
int main(){
int N, c, d;
int a[24]={0,1};
//第二十三行有23个数,加上第一个0,总共24,初始化前两个0和1
//后面所有的数都是由这前两个数计算得来
printf("请输入杨辉三角形的行数(1 ~ 23):");
scanf("%d",&N);
for(int i = 1; i <= N; i++){
for(int j = N - i; j >= 1; j--)
printf(" ");
d = 0;
for(int j = 1; j <= i; j++){
c = a[j];
a[j] = d + c;
d = c;
printf(" %7d", a[j]);
}
printf("\n");
}
return 0;
}
以上代码可以修改,增加数组长度可以增加打印杨辉三角的行数
法四:递归
递归调用,函数本身不断调用自己。递归调用思维性技巧性比较强,代码也比较简短,但其空间复杂度较大,因为其不断调用自己本身这个函数,在内存中不断开辟函数入口,占内存较大,由于计算机计算速度较快,我们并不能感受到。这个算法建立在前面两个算法之上
#include <stdio.h>
int fun(int a, int b){
//函数的递归调用,函数自己不断调用自己,产生多个子函数程序入口,并返回值相加
//函数的程序入口为一个内存地址
return (b == 1 || b == a) ? 1 : fun( a - 1, b - 1 ) + fun( a - 1, b );
//三目条件运算符的应用
}
int main(){
int N;
printf("请输入杨辉三角形的行数(1 ~ 23):");
scanf("%d", &N);
for(int i = 1; i <= N; i++){
for(int j = N - i; j > 0; j--)
printf(" ");
for(int j = 1; j <= i; j++)
printf(" %7d", fun(i, j));
putchar('\n'); //单个转义字符putchar输出
}
return 0;
}
调试:
Java实现
Java语言实现,采用C语言中的法三
import java.util.Scanner;
public class Example {
public static void main(String args[]){
System.out.print("请输入打印杨辉三角的行数(1~23行):");
Scanner input = new Scanner(System.in);
int N = input.nextInt();
int a[] = new int[24];a[0]=0;a[1]=1;
int c, d;
for(int i = 1; i <= N; i++){
for(int j = N - i; j >= 1; j--)
System.out.printf(" ");
d = 0;
for(int j = 1; j <= i; j++){
c = a[j];
a[j] = d + c;
d = c;
System.out.printf(" %7d", a[j]);
}
System.out.println();
}
}
}
Python实现
在python中并没有数据类型存储数据范围的限制,所以可以用数学公式法来打印,行数也会不受到限制
def factorial(a, b):
fact = 1
for i in range(a, b + 1):
fact *= i
return fact
def comb(m, n):
if m == 0:
return 1
elif m == n:
return 1
else:
return factorial(n - m + 1, n)/factorial(1, m)
n = int(input("请输入打印杨辉三角的行数:"))
for i in range(0, n):
for j in range(n - 1 - i, 0, -1):
print(" ", end='')
for j in range(0, i + 1):
print("%7d " % comb(j, i), end='')
print()
运行: