プログラム中のkとnは実際コンストラクタ等で与えておきます。
kが変化すると呼び出すfor文の回数も変わるので再起処理しています。
public class Duplication {
static int idx = 0;
/**
* @param args
*/
public static void main(String[] args) {
// TODO 自動生成されたメソッド・スタブ
int k = 5, n = 10; //実際はコンストラクタで初期化
int k_sum = 0, roop = 0;
long h = (fact(k+n-1)/(fact(n)*fact(k-1)));
int[][] combi = new int[(int)h][k]; //結果を格納のする配列(最終結果)
int[] k_mem = new int[k]; //各ループで上書き
System.out.println("今回はK="+k+", N="+n+"で"+k+"H"+n+"="+(k+n-1)+"C"+n+"となり"+(fact(k+n-1)/(fact(n)*fact(k-1)))+"通りあります");
dupricate(k_mem, k_sum, k, n, roop, combi);
int l = 0;
for (int[] array : combi) {
l++;
System.out.print("["+l+"]");
for (int element : array) {
System.out.print(element);
}
System.out.println("");
}
}
static long fact(long num){
long i;
if(num == 1){
return 1;
} else {
i = num * fact(num - 1);
return i;
}
}
/**
* @param k_mem[] 各ループのk_iの値
* @param k_sum 今までのk_memの総和
* @param k 拠点数(定数)
* @param n 総台数(定数)
* @param roop 何回目の呼出か(最大K)
* @param combi 結果を格納
* @param idx combiの行番号0~h-1(クラス変数)
*/
static void dupricate(int k_mem[], int k_sum, int k, int n, int roop, int combi[][]){
roop ++; //呼び出された回数をアップ
for( int i = 0; i + k_sum <= n; i++){
k_mem[roop-1] = i; //k_memの要素にiを代入
k_sum += i; //k_sumにiを加える
if(roop == k){ //ループ回数がkに達した場合
if(k_sum == n){ //組み合わせが一致した場合
System.arraycopy(k_mem, 0, combi[idx], 0, k); //一致したらk_memをcombiにコピー
//void java.lang.System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
//System.out.println("COPY");
idx ++;
}
}else {
dupricate(k_mem, k_sum, k, n, roop, combi);
}
k_sum -= i; //今回行った和を戻す
}
}
}
0 件のコメント:
コメントを投稿