Permutation.java
/**
* @author slont
*/
public class Permutation {
private int number, list_size, searched, next_index;
private int[][] perm_list;
/**
* 引数の長さの順列を生成する
* @param num
*/
public Permutation(int num) {
this.number = num;
this.list_size = this.fact(this.number);
this.searched = 0;
this.next_index = 0;
this.perm_list = new int[this.list_size][this.number];
this.create(0, new int[this.number], new boolean[this.number]);
}
public static void main(String[] args) {
Permutation pmt = new Permutation(4);
while(pmt.isNext()) {
printNum(pmt.nextPerm());
}
}
/**
* 生成された順列をint配列で返す
* @return int[]
*/
public int[] nextPerm() {
this.next_index++;
return perm_list[this.next_index-1];
}
/**
* 取り出せる順列が存在する場合にtrue、存在しない場合はfalseを返す
* @return boolean
*/
public boolean isNext() {
if(this.next_index < this.list_size) {
return true;
} else {
this.next_index = 0;
return false;
}
}
/** 引数の階乗を返す **/
private int fact(int n) {
return n == 0 ? 1 : n * fact(n-1);
}
/** 順列を作る **/
private void create(int _num, int[] _list, boolean[] _flag) {
if(_num == this.number) {
copyArray(_list, perm_list[this.searched]);
this.searched++;
}
for(int i=0; i if(_flag[i]) continue;
_list[_num] = i;
_flag[i] = true;
this.create(_num+1, _list, _flag);
_flag[i] = false;
}
}
/** int配列をコピーする **/
private static void copyArray(int[] _from, int[] _to) {
for(int i=0; i<_from.length; i++) _to[i] = _from[i];
}
/** int配列を標準出力する **/
private static void printNum(int[] _nums) {
for(int n : _nums) System.out.print(n);
System.out.println();
}
}
出力
0123
0132
0213
0231
0312
0321
1023
1032
1203
1230
1302
1320
2013
2031
2103
2130
2301
2310
3012
3021
3102
3120
3201
3210
使い方はmain関数の中です。私が直感的に使いやすいようにnext()みたいなの使ってますが、生成したものを直接使っても良いです。再帰を使っているので、数字10個とかになると結構アウトです(笑)参考までに。