一、程序設計思想:
(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("是否想繼續計算?\n1.繼續 \t2.按任意鍵退出");
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("是否想繼續計算?\n1.繼續 \t2.按任意鍵退出");
int input=in.nextInt();
if(input==1) {
judge=true;
}
else {
judge=false;
System.out.println("已退出程序!");
}
}
else {
System.out.print("輸入錯誤!\n請重新");
}
}
}
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)使用遞歸的方法用組合數遞推公式計算:
遞歸的方法使代碼量較少,需要用遞歸算法解決的問題,其規模通常都是比較大的。遞推算法在求解的過程中,每一個中間量都是已知,而且沒有重復計算,運算簡潔,但是書寫代碼和理解代碼比較難。