前言
This Series aritcles are all based on the book 《经典算法大全》; 对于该书的所有案例进行一个探究和拓展,并且用python和C++进行实现; 目的是熟悉常用算法过程中的技巧和逻辑拓展。
提出问题
打印出下面的这个图形。巴斯卡三角形,下面的一个数为上面两个数的和。
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
1 11 55 165 330 461 461 329 164 54 10 0
1 12 66 220 495 792 924 792 495 220 66 12 1
分析和解释
这是个非常简单的基础题; 跟打印乘法口诀表的行为类似; 外层循环控制行数,内层循环,控制每一行的表现, 首先我们要缩进N-n+1次。
才开始打印数字,接着换行依次如此, 关于对角和为组合数Nchoosk(n,k); 就是在N个数中选择K个数的组合数。
python 使用了 reduce匿函数列表推导式来生成nchoosk()。
代码
python 实现
import functools as ft
def nchooser(n,k):
if k==0: return 1
return ft.reduce(lambda x,y:x*y,[(n-i+1)/i for i in [x+1 for x in range(k)]])
def paint():
N=12;
for n in range(N+1):
for r in range(n+1):
if(r==0):
for i in range(N-n+1):
print(" ",end="")
else:
print(" ",end = "")
print(int(nchooser(n,r)),end="")
print()
paint()
C++ 实现
#include<iostream>
#define N 10
using namespace std;
long nchoosek(int n, int k)
{
int i;
long p=1;
for(i=0; i<=k; i++)
p *= (n-i+1) / i;
return p;
}
int paint()
{
int n,r,t;
for( n=0; n<=N; n++)
{
for( r=0; r<= n; r++ )
{
int i;
if(r==0)
{
for(i=0; i<= (N-n); i++)
cout <<" ";
}else {cout << " ";}
cout << nchoosek(n,r);
}
cout << endl;
}
return 0;
}
int main()
{
paint();
}
”’
拓展和关联
关于更多打印的问题可以关注知乎”怎么打印星形”,或者搜索相关的打印题目练习。
再拓展, 关注我后期文章系列 <计算机图形学>
后记
参考书籍
- 《经典算法大全》
- 维基百科