import
java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
/**
*
* @author Daniel
* 排列、组合公共操作应用类
*
*/
public class MyArraysUtil {
public static void main(String[] args) {
String array[] = { " 0 " , " 1 " , " 2 " , " 3 " , " 4 " , " 5 " , " 6 " , " 7 " , " 8 " , " 9 " };
// testSubArray();
testPerm(array, 3 );
// 递归法测试
testDaffodil(array, 3 );
}
/** ************ 非递归排列测试 *************** */
public static void testPerm(Object[] array, int m){
long t1 = System.currentTimeMillis();
Object[] arr = subArraysByLength(array,m);
List < Object[] > list = new ArrayList < Object[] > ();
for ( int i = 0 ; i < arr.length; i ++ ){
list.add(perm((Object[])arr[i]));
}
Object[] _arr = (Object[])list.toArray( new Object[list.size()]);
System.out.println(Arrays.deepToString(_arr));
long t2 = System.currentTimeMillis();
System.out.println( " 非递归一共有 " + _arr.length + " 个全排列集合. " );
System.out.println( " 非递归一共用时 " + (t2 - t1) + " 毫秒. " );
}
/** ************************************************************ */
/** ******************* 排列组合的应用:水仙花数 **************** */
/** ************************************************************ */
public static void testDaffodil(Object[] array, int m){
long t1 = System.currentTimeMillis();
Object[] arr = subArraysByLength(array,m);
List < Object[] > list = new ArrayList < Object[] > ();
for ( int i = 0 ; i < arr.length; i ++ ){
List < Object[] > _list = new ArrayList < Object[] > ();
Object[] _arr = (Object[])arr[i]; // [1,2,3]
getPerm(_arr,_list);
list.add((Object[])_list.toArray( new Object[_list.size()]));
}
Object[] rt = (Object[])list.toArray( new Object[list.size()]);
System.out.println(Arrays.deepToString(rt));
long t2 = System.currentTimeMillis();
System.out.println( " 递归一共有 " + rt.length + " 个全排列集合. " );
System.out.println( " 递归一共用时 " + (t2 - t1) + " 毫秒. " );
}
/** ****************** 组合(子集合)测试 ************************ */
public static void testSubArray(){
String array[] = { " 1 " , " 2 " , " 3 " , " 4 " , " 5 " , " 6 " , " 7 " , " 8 " , " 9 " , " a " , " b " , " c " , " d " , " e " , " f " };
long t1 = System.currentTimeMillis();
Object[] arr = subArraysByLength(array, 8 );
System.out.println(Arrays.deepToString(arr));
System.out.println( " 一共有 " + arr.length + " 个元素. " );
long t2 = System.currentTimeMillis();
System.out.println( " 一共花费时间 " + (t2 - t1) + " 毫秒. " );
}
/** ************************************************************ */
/** ********* 以下是排列操作 *************** */
/** *********************************************************** */
/** *************** 第一种方法:递归法 ******************************** */
/**
* 对array中的元素全排列,结果以数组的形式保存在list中
* @param array
* @param list
*/
public static void getPerm(Object[] array,List < Object[] > list){
perm(array, 0 ,array.length,list);
}
/**
* 用递归取排列数
* @param array
* @param m
* @param n
* @param list
*/
private static void perm(Object[] array, int m, int n,List < Object[] > list){
if (array == null ){
list = new ArrayList < Object[] > ();
return ;
}
// 用array的copy进行排列
Object[] _array = Arrays.copyOf(array, array.length);
if (m < n - 1 ) {
perm(_array, m + 1 , n,list);
for ( int i = m + 1 ;i < n;i ++ ) {
Object t = _array[m];
_array[m] = _array[i];
_array[i] = t;
perm(_array, m + 1 , n,list);
t = _array[m];
_array[m] = _array[i];
_array[i] = t;
}
} else {
list.add(_array);
}
}
/** ****************** 排列第二种方法:移位法 ********************** */
/**
* 不重复元素数组array中的元素全排列
* 非递归算法
* @param array
* @return
*/
public static Object[] perm(Object[] array){
if (array == null || array.length <= 1 ){
return array;
}
Queue < ArrayWrapper > queue = new LinkedList < ArrayWrapper > ();
int len = array.length;
int cnt = 0 ;
queue.offer( new ArrayWrapper(array, 0 ));
while (cnt < len){
Object[] _array = array;
if ( ! queue.isEmpty()){
ArrayWrapper _tmp = queue.poll();
_array = _tmp.getArray();
cnt = _tmp.getSign();
}
for ( int j = 0 ; j < len - cnt; j ++ ){
ArrayWrapper _aw = new ArrayWrapper(shiftLeft(_array,len - cnt,j),cnt + 1 );
queue.offer(_aw);
}
cnt ++ ;
}
int total = queue.size();
Object[] result = new Object[total];
for ( int i = 0 ; i < total; i ++ ){
result[i] = queue.poll().getArray();
}
return result;
}
/*
* 有序数组array中的左起m个元素左移n位,最高位回到最低位
*/
private static Object[] shiftLeft(Object[] array, int m, int n){
if (array == null || array.length <= 1 ){
return array;
}
if (m <= 1 ){
return array;
}
int length = array.length;
Object[] _temp = new Object[length];
int _n = n % m;
System.arraycopy(array, _n, _temp, 0 , m - _n);
System.arraycopy(array, 0 , _temp, m - _n, _n);
System.arraycopy(array, m, _temp, m, length - m);
return _temp;
}
/** ************************************************************** */
/** ************ 以下是组合算法及应用 ************* */
/** ************************************************************** */
/** ****** array中含有eleNum个元素的所有子集****** */
/**
* 取得集合array的所有长度为eleNum的子集合
* 若eleNum<0则取得所有子集合
* @param array
* @param length
* @return
*/
public static Object[] subArraysByLength(Object[] array, int eleNum){
if (array == null ){
return null ;
}
int length = array.length;
List < Object[] > list = new ArrayList < Object[] > ();
for ( int i = 0 ; i < ( 1 << length); i ++ ){
if ( ! (eleNum < 0 || get1Cnt(i) == eleNum)){
continue ;
}
List < Object > _list = new ArrayList < Object > ();
for ( int j = 0 ; j < length; j ++ ){
if ((i & ( 1 << j)) != 0 ){
_list.add(array[j]);
}
}
list.add(_list.toArray( new Object[_list.size()]));
}
return list.toArray( new Object[list.size()]);
}
/**
* 取得二进制正整数中"1"的个数
* @param num
* @return
*/
private static int get1Cnt( int num){
int cnt = 0 ;
for (;num > 0 ;num >>= 1 ){
cnt += (num & 1 );
}
return cnt;
}
}
/**
* array数组封装类,加了个标签sign
* @author Daniel
*
*/
class ArrayWrapper{
private Object[] array;
private int sign;
public ArrayWrapper(Object[] array, int sign){
this .array = array;
this .sign = sign;
}
public Object[] getArray() {
return array;
}
public int getSign() {
return sign;
}
}
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
/**
*
* @author Daniel
* 排列、组合公共操作应用类
*
*/
public class MyArraysUtil {
public static void main(String[] args) {
String array[] = { " 0 " , " 1 " , " 2 " , " 3 " , " 4 " , " 5 " , " 6 " , " 7 " , " 8 " , " 9 " };
// testSubArray();
testPerm(array, 3 );
// 递归法测试
testDaffodil(array, 3 );
}
/** ************ 非递归排列测试 *************** */
public static void testPerm(Object[] array, int m){
long t1 = System.currentTimeMillis();
Object[] arr = subArraysByLength(array,m);
List < Object[] > list = new ArrayList < Object[] > ();
for ( int i = 0 ; i < arr.length; i ++ ){
list.add(perm((Object[])arr[i]));
}
Object[] _arr = (Object[])list.toArray( new Object[list.size()]);
System.out.println(Arrays.deepToString(_arr));
long t2 = System.currentTimeMillis();
System.out.println( " 非递归一共有 " + _arr.length + " 个全排列集合. " );
System.out.println( " 非递归一共用时 " + (t2 - t1) + " 毫秒. " );
}
/** ************************************************************ */
/** ******************* 排列组合的应用:水仙花数 **************** */
/** ************************************************************ */
public static void testDaffodil(Object[] array, int m){
long t1 = System.currentTimeMillis();
Object[] arr = subArraysByLength(array,m);
List < Object[] > list = new ArrayList < Object[] > ();
for ( int i = 0 ; i < arr.length; i ++ ){
List < Object[] > _list = new ArrayList < Object[] > ();
Object[] _arr = (Object[])arr[i]; // [1,2,3]
getPerm(_arr,_list);
list.add((Object[])_list.toArray( new Object[_list.size()]));
}
Object[] rt = (Object[])list.toArray( new Object[list.size()]);
System.out.println(Arrays.deepToString(rt));
long t2 = System.currentTimeMillis();
System.out.println( " 递归一共有 " + rt.length + " 个全排列集合. " );
System.out.println( " 递归一共用时 " + (t2 - t1) + " 毫秒. " );
}
/** ****************** 组合(子集合)测试 ************************ */
public static void testSubArray(){
String array[] = { " 1 " , " 2 " , " 3 " , " 4 " , " 5 " , " 6 " , " 7 " , " 8 " , " 9 " , " a " , " b " , " c " , " d " , " e " , " f " };
long t1 = System.currentTimeMillis();
Object[] arr = subArraysByLength(array, 8 );
System.out.println(Arrays.deepToString(arr));
System.out.println( " 一共有 " + arr.length + " 个元素. " );
long t2 = System.currentTimeMillis();
System.out.println( " 一共花费时间 " + (t2 - t1) + " 毫秒. " );
}
/** ************************************************************ */
/** ********* 以下是排列操作 *************** */
/** *********************************************************** */
/** *************** 第一种方法:递归法 ******************************** */
/**
* 对array中的元素全排列,结果以数组的形式保存在list中
* @param array
* @param list
*/
public static void getPerm(Object[] array,List < Object[] > list){
perm(array, 0 ,array.length,list);
}
/**
* 用递归取排列数
* @param array
* @param m
* @param n
* @param list
*/
private static void perm(Object[] array, int m, int n,List < Object[] > list){
if (array == null ){
list = new ArrayList < Object[] > ();
return ;
}
// 用array的copy进行排列
Object[] _array = Arrays.copyOf(array, array.length);
if (m < n - 1 ) {
perm(_array, m + 1 , n,list);
for ( int i = m + 1 ;i < n;i ++ ) {
Object t = _array[m];
_array[m] = _array[i];
_array[i] = t;
perm(_array, m + 1 , n,list);
t = _array[m];
_array[m] = _array[i];
_array[i] = t;
}
} else {
list.add(_array);
}
}
/** ****************** 排列第二种方法:移位法 ********************** */
/**
* 不重复元素数组array中的元素全排列
* 非递归算法
* @param array
* @return
*/
public static Object[] perm(Object[] array){
if (array == null || array.length <= 1 ){
return array;
}
Queue < ArrayWrapper > queue = new LinkedList < ArrayWrapper > ();
int len = array.length;
int cnt = 0 ;
queue.offer( new ArrayWrapper(array, 0 ));
while (cnt < len){
Object[] _array = array;
if ( ! queue.isEmpty()){
ArrayWrapper _tmp = queue.poll();
_array = _tmp.getArray();
cnt = _tmp.getSign();
}
for ( int j = 0 ; j < len - cnt; j ++ ){
ArrayWrapper _aw = new ArrayWrapper(shiftLeft(_array,len - cnt,j),cnt + 1 );
queue.offer(_aw);
}
cnt ++ ;
}
int total = queue.size();
Object[] result = new Object[total];
for ( int i = 0 ; i < total; i ++ ){
result[i] = queue.poll().getArray();
}
return result;
}
/*
* 有序数组array中的左起m个元素左移n位,最高位回到最低位
*/
private static Object[] shiftLeft(Object[] array, int m, int n){
if (array == null || array.length <= 1 ){
return array;
}
if (m <= 1 ){
return array;
}
int length = array.length;
Object[] _temp = new Object[length];
int _n = n % m;
System.arraycopy(array, _n, _temp, 0 , m - _n);
System.arraycopy(array, 0 , _temp, m - _n, _n);
System.arraycopy(array, m, _temp, m, length - m);
return _temp;
}
/** ************************************************************** */
/** ************ 以下是组合算法及应用 ************* */
/** ************************************************************** */
/** ****** array中含有eleNum个元素的所有子集****** */
/**
* 取得集合array的所有长度为eleNum的子集合
* 若eleNum<0则取得所有子集合
* @param array
* @param length
* @return
*/
public static Object[] subArraysByLength(Object[] array, int eleNum){
if (array == null ){
return null ;
}
int length = array.length;
List < Object[] > list = new ArrayList < Object[] > ();
for ( int i = 0 ; i < ( 1 << length); i ++ ){
if ( ! (eleNum < 0 || get1Cnt(i) == eleNum)){
continue ;
}
List < Object > _list = new ArrayList < Object > ();
for ( int j = 0 ; j < length; j ++ ){
if ((i & ( 1 << j)) != 0 ){
_list.add(array[j]);
}
}
list.add(_list.toArray( new Object[_list.size()]));
}
return list.toArray( new Object[list.size()]);
}
/**
* 取得二进制正整数中"1"的个数
* @param num
* @return
*/
private static int get1Cnt( int num){
int cnt = 0 ;
for (;num > 0 ;num >>= 1 ){
cnt += (num & 1 );
}
return cnt;
}
}
/**
* array数组封装类,加了个标签sign
* @author Daniel
*
*/
class ArrayWrapper{
private Object[] array;
private int sign;
public ArrayWrapper(Object[] array, int sign){
this .array = array;
this .sign = sign;
}
public Object[] getArray() {
return array;
}
public int getSign() {
return sign;
}
}