一、程序设计思想:
(1)使用组合数公式利用n!来计算:
分别计算n!、k!、(n-k)!,之后再组合计算组合数。
(2)使用递推的方法用杨辉三角形计算:
先构造一个n行的二维数组用来存放组合数,通过发现第n行第k个数(有0行0列)就是(Cnk)的值,于是用两个循环for(int i=0;i<=n;i++)和for(int j=0;j<=i;j++)(每行可存的数=行数)即可找到a[n][k]。
另外为了增加程序友好性,本程序可让用户选择“1.继续计算 2.按任意键退出”,还通过输入的n、k值是否符合“n>0&&k>=0”,符合则运算,不符合则重新输入。
(3)使用递归的方法用组合数递推公式计算:
递归就需要从n行k列开始依次往回找到第一个数,利用fac(n-1,k)递归;当n==0时,就return 1。为了提高程序友好性,采取了如题(2)使用的while()循环和输入是否正确的判断。
二、程序流程图:
(1)使用组合数公式利用n!来计算:
(2)使用递推的方法用杨辉三角形计算:
(3)使用递归的方法用组合数递推公式计算:
三、源程序:
(1)使用组合数公式利用n!来计算:
package homework2;
import java.util.Scanner;
public class YangHui_Triangle {
public static void main(String[] args) {
// TODO Auto-generated method stub
int n1=1,k1=1,nk=1;
System.out.println("依次输入(Cnk)的n、k值以计算组合数:");
Scanner in=new Scanner(System.in);
int n=in.nextInt();
int k=in.nextInt();
for(int i=1;i<=k;i++) {
k1=k1*i;
}
for(int i=1;i<=n;i++) {
n1=n1*i;
}
for(int i=1;i<=n-k;i++) {
nk=nk*i;
}
System.out.println("Cnk的值为:"+(n1/(k1*nk)));
}
}
(2)使用递推的方法用杨辉三角形计算:
//递推方法用杨辉三角行计算组合数
package homework2;
import java.util.Scanner;
public class YangHui_Triangle_Recursion {
public static void main(String[] args) {
// TODO Auto-generated method stub
boolean select=true;//判断是否继续运算
while(select) {
System.out.println("依次输入(Cnk)的n、k值以计算组合数:");
// YangHui_Triangle_DiTui A=new YangHui_Triangle_DiTui();
Scanner in=new Scanner(System.in);
int n=in.nextInt();
int k=in.nextInt();
if(k>=0&&n>0) {
int [][]a=new int[n+1][n+1];//定义一个刚好和n相等的二维数组,以免过多浪费空间
int i=0,j=0;
for(i=0;i<=n;i++){
for(j=0;j<=i;j++){
if(j>0) {
a[i][j]=a[i-1][j-1]+a[i-1][j];
}
if(j==0||j==i) {
a[i][j]=1;
}
}
}
System.out.println("(Cnk)的值为:"+a[n][k]);
System.out.println("是否想继续计算? 1.继续 2.按任意键退出");
int input=in.nextInt();
if(input==1) {
select=true;
}
else {
select=false;
System.out.println("已退出程序!");
}
}
else System.out.println("输入错误!请再次");
}
}
}
(3)使用递归的方法用组合数递推公式计算:
package homework2;
import java.util.Scanner;
public class YangHui_Triangle_DiGui {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in=new Scanner(System.in);
boolean judge=true;
int n;
int k;
while(judge) {
YangHui_Triangle_DiGui Tri=new YangHui_Triangle_DiGui();
System.out.println("依次输入(Cnk)的n、k值以计算组合数:");
n=in.nextInt();
k=in.nextInt();
int result=0;
int [][]a=new int[n+1][n+1];//设置一个n+1的数组,以免浪费空间。
if(n>0&&k>=0&&k<=n) {
{
result=Tri.fac(n, k);
}//递归计算
System.out.println("(Cnk)的值为:"+result);
System.out.println("是否想继续计算? 1.继续 2.按任意键退出");
int input=in.nextInt();
if(input==1) {
judge=true;
}
else {
judge=false;
System.out.println("已退出程序!");
}
}
else {
System.out.print("输入错误! 请重新");
}
}
}
public static int fac(int n,int k) {
if(k==n||k==0) {
return 1;
}
else{
return (fac(n-1,k-1)+fac(n-1,k));
}
}
}
四、实现结果截图:
(1)使用组合数公式利用n!来计算:
(2)使用递推的方法用杨辉三角形计算:
(3)使用递归的方法用组合数递推公式计算:
(输入错误!提示再次输入n、k值:)
(可选择是否继续程序。)
五、实验总结:
(1)使用组合数公式利用n!来计算:
通过拆分式子利用三个循环计算组合数,这个算法相对简单。
(2)使用递推的方法用杨辉三角形计算:
“递推”与 “递归”的区别就是,“递推”从第一个开始到最后一个,“递归”从第n个开始计算返回到第一个,这样的算法相对“递归”浪费时间。
(3)使用递归的方法用组合数递推公式计算:
递归的方法使代码量较少,需要用递归算法解决的问题,其规模通常都是比较大的。递推算法在求解的过程中,每一个中间量都是已知,而且没有重复计算,运算简洁,但是书写代码和理解代码比较难。