遞歸(計算組合數、判斷回文字符串、漢諾塔問題)
一.使用組合數公式利用n!來計算
1.設計思想
先輸入整數n和k,分別用計算n!的遞歸的方法算出n!,k!和(n-k)!的結果,再計算n!/(k!(n-k)!!。用大數類BigInteger來表示n!,k!和(n-k)!的返回類型。最後輸出計算的結果。
2.流程圖
3.源程序代碼
import java.util.Scanner;
import java.math.BigInteger;
public class Number1 {
static BigInteger GetN(int n ){//求n!
if(n==1 || n==0){
return BigInteger.valueOf(1);
}
return BigInteger.valueOf(n).multiply(GetN(n-1));
}
static BigInteger GetK(int k) {//求k!
if(k==1||k==0) {
return BigInteger.valueOf(1);
}
return BigInteger.valueOf(k).multiply(GetK(k-1));
}
static BigInteger GetN_K(int N_K) {//求(n-k)!
if(N_K==1||N_K==0) {
return BigInteger.valueOf(1);
}
return BigInteger.valueOf(N_K).multiply(GetN_K(N_K-1));
}
public static void main(String[] args) {
BigInteger result,i;
Scanner scanner=new Scanner(System.in);
System.out.println("請輸入組合式[n!/(k!*(n-k)!)]中的n和k(n和k之間用空格空開)");
int n=scanner.nextInt();
int k=scanner.nextInt();
i=GetK(k).multiply(GetN_K(n-k));//計算i=k!*(n-k)!;
result=GetN(n).divide(i);//計算result=n!/i;
System.out.println("n!/(k!*(n-k)!)="+result);
}
}
4.結果截圖
二.使用遞推的方法用楊輝三角形計算
1.設計思想
先輸入n和k,n一定會比k大,動態申請一個大小為n的二維數組,利用楊輝三角(楊輝三角的行是n-1,列是k-1,楊輝三角二維素組的值是組合數的值)來計算組合數的值。用for循環給數組賦值。最後輸出數組[n-1][k-1]的值。
2.流程圖
3.源程序代碼
import java.util.Scanner;
import java.math.BigInteger;
public class Number2 {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.println("請輸入組合式[n!/(k!*(n-k)!)]中的n和k(n和k之間用空格空開)");
int n=scanner.nextInt();
int k=scanner.nextInt();
BigInteger[][] a=new BigInteger[n][n];//a[i][j]存放n!/(k!*(n-k)!的結果,i代表n,j代表k
for(int i=0;i<n;i++) {
for(int j=0;j<n;j++) {
if((i==0)&&(j==0))//0!/(0!*(0-0)!
a[i][j]=BigInteger.valueOf(1);
else if(j==0||j==i)
a[i][j]=BigInteger.valueOf(1);
else if(j<=i)
a[i][j]=a[i-1][j-1].add(a[i-1][j]);
else //當n小於k時,不計算n!/(k!*(n-k)!,數組a[i][j]=0
a[i][j]=BigInteger.valueOf(0);
}
}
System.out.println("n!/(k!*(n-k)!)="+a[n-1][k-1]);
}
}
4.結果截圖
三.判斷回文字符串
1.設計思想
先根據提示輸入一段String字符串,將String型字符串轉化成char[] 型字符串,再確定字符串的第一個字符下標和最後一個字符下標。再寫返回值是boolean型的判斷兩個字符是否相等的方法,把字符串和第一個字符下標和最後一個字符下標作為形參。判斷字符是否相等的函數裏,依次從字符串兩端到中間判斷字符是否相等,若相等返回true,否則返回false。
2.程序流程圖
3.程序源代碼
import java.util.Scanner;
public class Huiwen {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.println("請輸入一段字符串:");
String in=scanner.next();//輸入字符串
int w=in.length()-1;//w是字符串最後一個字符的下標
char[] inn=in.toCharArray();//將String型轉換成char[]型
if(isHuiwen(inn,0,w)==true) {//從兩端到中間的字符串都回文
System.out.println("此字符串是回文字符串");
}
else {
System.out.println("此字符串不是回文字符串");
}
}
static boolean isHuiwen(char[] inn,int t,int w) {//判斷兩個字符是否相等
if((w-t)==1||(w-t)==2||(w-t)==0) {//(w-t)==1輸入的字符串字符個數為偶數個,(w-t)==2輸入的字符串字符個數位奇數個,(w-t)==0輸入的字符串只有一個字符
if(inn[w]==inn[t]){//最中間的兩個字符相等
return true;
}
else
return false;//如果判斷兩個字符不相等,不用再遞歸,返回false
}
else {
if(inn[w]==inn[t]) {
return true &&isHuiwen(inn,t+1,w-1);//如果判斷的兩個字符相等,在判斷靠近中間的兩個字符
}
else {
return false;
}
}
}
}
4.結果截圖
四、漢諾塔問題
1.設計思想
在main輸入漢諾塔問題中a指針上的盤子的個數,再調用遞歸方法輸出移動盤子的次數。再用一個遞歸方法來寫盤子從a指針上移動到c指針上的過程。a指針上按照從大到小的盤子n個,先從a指針移動到b指針上n-1個,這時最大的一個盤子再從a指針上移動到c指針上,b指針上的盤子n-1個按照從小到大的順序排列。這時再將盤子從b盤上移動到c盤上。這是c指針上的n個盤子按照從大到小的順序排列·。
2.程序流程圖
3.程序源代碼
import java.util.Scanner;
public class Tower {
public static void main(String[] args) {
System.out.println("漢諾塔問題:請輸入a指針上的盤子的個數:");
Scanner scanner=new Scanner(System.in);
int n=scanner.nextInt();
int num=0,a=n,b=0,c=0;
System.out.println("將a指針上所有的盤子移到c指針上需要移動"+Yidong(num,a,b,c,n)+"次。");
}
static int Yidong(int num,int a,int b,int c,int n) {//盤子從a盤移動到c盤的過程
if(a>1) {//盤子從a指針上移到b指針上
b++;
a--;
System.out.println("把一個盤子從a指針上移到b指針上");
return Yidong(num+1,a,b,c,n);
}
else if(a==1) {//a指針上的盤子只剩一個,把a指針上的最後一個盤子移到c指針上
c++;
a--;
System.out.println("把a指針上的最後一個盤子移到c指針上");
return Yidong(num+1,a,b,c,n);
}
else if(c==n){//當所有的盤子都移動到c指針上
System.out.println("所有的盤子都移動到c指針上");
return num;
}
else{//把b指針上的盤子移動到c指針上
c++;
b--;
System.out.println("把b指針上的一個盤子移動到c指針上");
return Yidong(num+1,a,b,c,n);
}
}
}
4.結果截圖
五、使用遞歸的方法用組合數遞推公式計算組合數
1.設計思想
2.程序流程圖
3.程序源代碼
import java.util.Scanner;
import java.math.BigInteger;
public class Number3 {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.println("請輸入組合式[n!/(k!*(n-k)!)]中的n和k(n和k之間用空格空開)");
int n=scanner.nextInt(); int k=scanner.nextInt();
System.out.println("n!/(k!*(n-k)!)="+GetNumber(n,k));
}
static BigInteger GetNumber(int n,int k) {
if(n==k||k==0) {
return BigInteger.valueOf(1);
}
else {
return GetNumber(n-1,k-1).add(GetNumber(n-1,k));
}
}
}
4.結果截圖
遞歸(計算組合數、判斷回文字符串、漢諾塔問題)